package main

import (
	"bytes"
	"fmt"
	"io"
	"log"
	"mime/multipart"
	"net/http"
	"os"
	"os/exec"
	"strings"

	"github.com/atotto/clipboard"
	"golang.org/x/sys/windows/registry"
)

func main() {
	if len(os.Args) > 1 {
		switch os.Args[1] {
		case "install":
			installContextMenuItem()
		case "uninstall":
			ensureAdminPrivileges()
			uninstallContextMenuItem()
		default:
			processFile(os.Args[1])
		}
	} else {
		log.Println("No file provided")
	}
}

func processFile(filePath string) {
	log.Printf("Processing file: %s", filePath)
	url, err := uploadFile(filePath)
	if err != nil {
		log.Fatalf("Failed to upload file: %v", err)
	}
	err = clipboard.WriteAll(url)
	if err != nil {
		log.Fatalf("Failed to copy URL to clipboard: %v", err)
	}
	log.Printf("URL copied to clipboard: %s", url)
}

func uploadFile(filename string) (string, error) {
	file, err := os.Open(filename)
	if err != nil {
		return "", fmt.Errorf("failed to open file: %w", err)
	}
	defer file.Close()

	body := &bytes.Buffer{}
	writer := multipart.NewWriter(body)
	part, err := writer.CreateFormFile("file", filename)
	if err != nil {
		return "", fmt.Errorf("failed to create form file: %w", err)
	}
	_, err = io.Copy(part, file)
	if err != nil {
		return "", fmt.Errorf("failed to copy file data: %w", err)
	}

	writer.Close()

	request, err := http.NewRequest("POST", "https://send.aenow.com/upload", body)
	if err != nil {
		return "", fmt.Errorf("failed to create request: %w", err)
	}
	request.Header.Set("Content-Type", writer.FormDataContentType())

	client := &http.Client{}
	response, err := client.Do(request)
	if err != nil {
		return "", fmt.Errorf("failed to send request: %w", err)
	}
	defer response.Body.Close()

	urlBytes, err := io.ReadAll(response.Body)
	if err != nil {
		return "", fmt.Errorf("failed to read response: %w", err)
	}

	return string(urlBytes), nil
}

func installContextMenuItem() {
	exePath, _ := os.Executable()
	keyPath := `Software\Classes\*\shell\AE Send`
	command := "\"" + exePath + "\" \"%1\""

	k, _, err := registry.CreateKey(registry.CURRENT_USER, keyPath, registry.ALL_ACCESS)
	if err != nil {
		log.Fatalf("Failed to create registry key: %v", err)
		return
	}
	defer k.Close()

	err = k.SetStringValue("", "Send with AE Send")
	if err != nil {
		log.Fatalf("Failed to set registry value: %v", err)
		return
	}

	commandKeyPath := keyPath + `\command`
	commandKey, _, err := registry.CreateKey(registry.CURRENT_USER, commandKeyPath, registry.ALL_ACCESS)
	if err != nil {
		log.Fatalf("Failed to create command key: %v", err)
		return
	}
	defer commandKey.Close()

	err = commandKey.SetStringValue("", command)
	if err != nil {
		log.Fatalf("Failed to set command: %v", err)
	}

	log.Println("Context menu item installed successfully.")
}

func uninstallContextMenuItem() {
	keyPath := `Software\Classes\*\shell\AE Send`
	err := registry.DeleteKey(registry.CURRENT_USER, keyPath)
	if err != nil {
		log.Fatalf("Failed to remove context menu item: %v", err)
	} else {
		log.Println("Context menu item removed successfully.")
	}
}

func ensureAdminPrivileges() {
	if !isAdmin() {
		// Relaunch the application with elevated privileges
		exePath, _ := os.Executable()
		args := strings.Join(os.Args, " ")
		cmd := exec.Command("runas", "/user:Administrator", exePath+" "+args)
		err := cmd.Run()
		if err != nil {
			log.Fatalf("Failed to relaunch as admin: %v", err)
		}
		os.Exit(0)
	}
}

func isAdmin() bool {
	_, err := os.Open("\\\\.\\PHYSICALDRIVE0")
	return err == nil
}
