package main

import (
	"bytes"
	"encoding/json"
	"flag"
	"fmt"
	"io"
	"net/http"
	"os"
	"strconv"
)

func main() {
	// Define command-line flags
	var forgejoAPIURL string
	var token string
	var repoOwner string
	var repoName string
	var issueId int

	flag.StringVar(&forgejoAPIURL, "forgejo-api-url", "https://code.252.no/api/v1", "Forgejo API URL")
	flag.StringVar(&token, "token", "", "Forgejo API token")
	flag.StringVar(&repoOwner, "repo-owner", "", "Repository owner")
	flag.StringVar(&repoName, "repo-name", "", "Repository name")
	flag.IntVar(&issueId, "issue-id", 0, "Issue id")
	flag.Parse()

	// Get the diff file from the positional arguments
	args := flag.Args()
	if len(args) < 1 {
		fmt.Println("Usage: forgejo-comment <diff-file>")
		os.Exit(1)
	}
	diffFile := args[0]

	// Read environment variables if flags are not set
	if forgejoAPIURL == "" {
		forgejoAPIURL = os.Getenv("FORGEJO_API_URL")
		if forgejoAPIURL == "" {
			fmt.Println("Error: FORGEJO_API_URL is not set")
			os.Exit(1)
		}
	}

	if token == "" {
		token = os.Getenv("FORGEJO_TOKEN")
		if token == "" {
			fmt.Println("Error: FORGEJO_TOKEN is not set")
			os.Exit(1)
		}
	}

	if repoOwner == "" {
		repoOwner = os.Getenv("REPO_OWNER")
		if repoOwner == "" {
			fmt.Println("Error: REPO_OWNER is not set")
			os.Exit(1)
		}
	}

	if repoName == "" {
		repoName = os.Getenv("REPO_NAME")
		if repoName == "" {
			fmt.Println("Error: REPO_NAME is not set")
			os.Exit(1)
		}
	}

	if issueId == 0 {
		issueIdEnv := os.Getenv("ISSUE_ID")
		if issueIdEnv == "" {
			fmt.Println("Error: ISSUE_ID is not set")
			os.Exit(1)
		}
		var err error
		issueId, err = strconv.Atoi(issueIdEnv)
		if err != nil {
			fmt.Println("Error: Invalid ISSUE_ID")
			os.Exit(1)
		}
	}

	// Read the diff file
	diffContentBytes, err := os.ReadFile(diffFile)
	if err != nil {
		fmt.Printf("Error reading diff file: %v\n", err)
		os.Exit(1)
	}

	// Prepare the comment content
	diffContent := string(diffContentBytes)
	commentBody := fmt.Sprintf("```diff\n%s\n```", diffContent)

	// Prepare the request payload
	payload := map[string]string{
		"body": commentBody,
	}
	payloadBytes, err := json.Marshal(payload)
	if err != nil {
		fmt.Printf("Error marshaling payload: %v\n", err)
		os.Exit(1)
	}

	// Construct the API URL
	apiURL := fmt.Sprintf("%s/repos/%s/%s/issues/%d/comments", forgejoAPIURL, repoOwner, repoName, issueId)

	// Create the HTTP request
	req, err := http.NewRequest("POST", apiURL, bytes.NewBuffer(payloadBytes))
	if err != nil {
		fmt.Printf("Error creating request: %v\n", err)
		os.Exit(1)
	}

	req.Header.Set("Authorization", fmt.Sprintf("token %s", token))
	req.Header.Set("Content-Type", "application/json")

	// Send the request
	client := &http.Client{}
	resp, err := client.Do(req)
	if err != nil {
		fmt.Printf("Error sending request: %v\n", err)
		os.Exit(1)
	}
	defer resp.Body.Close()

	// Read the response body
	respBody, err := io.ReadAll(resp.Body)
	if err != nil {
		fmt.Printf("Error reading response: %v\n", err)
		os.Exit(1)
	}

	// Check the response status code
	if resp.StatusCode != 201 {
		fmt.Printf("Failed to post comment. HTTP status: %d\n", resp.StatusCode)
		fmt.Printf("Response body: %s\n", string(respBody))
		os.Exit(1)
	} else {
		fmt.Printf("Posted diff to Forgejo issue #%d\n", issueId)
	}
}
