package main

import (
	"context"
	"encoding/json"
	"fmt"
	"io/ioutil"
	"log"
	"net/http"
	"os"
	"strings"
	"time"

	"github.com/chromedp/chromedp"
)

func main() {
	if len(os.Args) < 2 {
		fmt.Println("Usage: go run main.go <url>")
		return
	}

	url := os.Args[1]
	if err := playVideo(url); err != nil {
		log.Fatal("Error:", err)
	}
}

func playVideo(url string) error {
	ctx, cancel := chromedp.NewContext(context.Background())
	defer cancel()

	ctx, cancel = context.WithTimeout(ctx, 5*time.Minute)
	defer cancel()

	options := []chromedp.ExecAllocatorOption{
		chromedp.ExecPath("/data/data/com.termux/files/usr/bin/chromium-browser"),
		chromedp.Headless,
		chromedp.NoSandbox,
		chromedp.DisableGPU,
		chromedp.IgnoreCertificateErrors,
	}

	ctx, cancel = chromedp.NewExecAllocator(ctx, options...)
	defer cancel()

	ctx, cancel = chromedp.NewContext(ctx)
	defer cancel()

	var firstResult string
	if err := chromedp.Run(ctx,
		chromedp.Navigate(url),
		chromedp.WaitVisible(b.api-key-text),
		chromedp.Text(b.api-key-text, &firstResult),
	); err != nil {
		return fmt.Errorf("error getting first result: %v", err)
	}

	currentURL := ""
	if err := chromedp.Run(ctx, chromedp.Location(&currentURL)); err != nil {
		return fmt.Errorf("error getting current URL: %v", err)
	}

	newURL := strings.Replace(currentURL, "UI/Dashboard", "api/v2.0/indexers?configured=true", 1)

	var responseBody []byte
	if err := chromedp.Run(ctx,
		chromedp.Navigate(newURL),
		chromedp.WaitVisible(body),
		chromedp.InnerHTML(body, &responseBody),
	); err != nil {
		return fmt.Errorf("error getting response body: %v", err)
	}

	var response []map[string]interface{}
	if err := json.Unmarshal(responseBody, &response); err != nil {
		return fmt.Errorf("error unmarshalling JSON response: %v", err)
	}

	privateItems := make([]map[string]interface{}, 0)
	for _, item := range response {
		itemType := strings.ToLower(fmt.Sprintf("%v", item["type"]))
		configured := strings.ToLower(fmt.Sprintf("%v", item["configured"]))

		if strings.Contains(itemType, "private") && configured == "true" {
			privateItems = append(privateItems, item)
		}
	}

	if len(privateItems) == 0 {
		return nil
	}

	fmt.Printf("\nTorznab key: %s\n", firstResult)

	for _, item := range privateItems {
		id := fmt.Sprintf("%v", item["id"])
		configURL := strings.Replace(currentURL, "UI/Dashboard", fmt.Sprintf("api/v2.0/indexers/%s/config", id), 1)

		configResponse, err := getConfigResponseWithCookies(configURL, ctx)
		if err != nil {
			fmt.Printf("##%s | %s | %v\n", id, configURL, err)
			continue
		}

		filteredElements := make([]string, 0)
		for _, element := range configResponse {
			elementType := fmt.Sprintf("%v", element["type"])
			elementValue := fmt.Sprintf("%v", element["value"])

			if elementType == "inputstring" && elementValue != "true" && elementValue != "false" {
				filteredElements = append(filteredElements, elementValue)
			}
		}

		groupedValues := strings.Join(filteredElements, " | ")
		prefixedGroupedValues := id + " | " + groupedValues
		fmt.Println(prefixedGroupedValues)
	}

	return nil
}

func getConfigResponseWithCookies(url string, ctx context.Context) ([]map[string]interface{}, error) {
	cookies, err := chromedp.Cookies(ctx)
	if err != nil {
		return nil, fmt.Errorf("error getting cookies: %v", err)
	}

	client := &http.Client{}
	req, err := http.NewRequest("GET", url, nil)
	if err != nil {
		return nil, fmt.Errorf("error creating request: %v", err)
	}

	for _, cookie := range cookies {
		req.AddCookie(&http.Cookie{
			Name:  cookie.Name,
			Value: cookie.Value,
		})
	}

	ctx, cancel := context.WithTimeout(ctx, 10*time.Second)
	defer cancel()

	req = req.WithContext(ctx)

	resp, err := client.Do(req)
	if err != nil {
		return nil, fmt.Errorf("error sending request: %v", err)
	}
	defer resp.Body.Close()

	body, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		return nil, fmt.Errorf("error reading response body: %v", err)
	}

	var response []map[string]interface{}
	if err := json.Unmarshal(body, &response); err != nil {
		return nil, fmt.Errorf("error unmarshalling JSON response: %v", err)
	}

	return response, nil
}