package main

import (
	"encoding/json"
	"fmt"
	"log"
	"net/http"
	"os/exec"
	"strings"
)

type ContainerInfo struct {
	ID       string
	Name     string
	CName    string
	Interval string
	Ignores  []string
}

func listContainersHandler(w http.ResponseWriter, r *http.Request) {
	containers, err := listContainers()
	if err != nil {
		http.Error(w, fmt.Sprintf("Error listing containers: %v", err), http.StatusInternalServerError)
		return
	}
	w.Header().Set("Content-Type", "application/json")
	if err := json.NewEncoder(w).Encode(containers); err != nil {
		http.Error(w, fmt.Sprintf("Error encoding response: %v", err), http.StatusInternalServerError)
	}
}

func getDiffHandler(w http.ResponseWriter, r *http.Request) {
	containerID := r.URL.Query().Get("id")
	if containerID == "" {
		http.Error(w, "Missing container ID", http.StatusBadRequest)
		return
	}
	diffOutput, err := getDiffOutput(containerID)
	if err != nil {
		http.Error(w, fmt.Sprintf("Error getting diff for container %s: %v", containerID, err), http.StatusInternalServerError)
		return
	}
	w.Header().Set("Content-Type", "text/plain")
	w.Write([]byte(diffOutput))
}

func startServer() {
	http.HandleFunc("/containers", listContainersHandler)
	http.HandleFunc("/diff", getDiffHandler)

	log.Println("Starting server on :8080")
	if err := http.ListenAndServe(":8080", nil); err != nil {
		log.Fatalf("Error starting server: %v", err)
	}
}

func listContainers() ([]ContainerInfo, error) {
	output, err := exec.Command("docker", "ps", "--format", "{{.ID}} {{.Names}} {{.Label \"oculus.enable\"}} {{.Label \"oculus.interval\"}} {{.Label \"oculus.cname\"}} {{.Label \"oculus.ignores\"}}").Output()
	if err != nil {
		return nil, err
	}

	lines := strings.Split(string(output), "\n")
	var containers []ContainerInfo

	for _, line := range lines {
		if line == "" {
			continue
		}
		parts := strings.Fields(line)
		if len(parts) < 3 || parts[2] == "" {
			continue
		}

		id := parts[0]
		name := parts[1]
		interval := "300s"
		if len(parts) > 3 && parts[3] != "" {
			interval = parts[3]
		}

		cname := name
		if len(parts) > 4 && parts[4] != "" {
			cname = parts[4]
		}

		ignores := []string{}
		if len(parts) > 5 && parts[5] != "" {
			ignores = strings.Split(parts[5], ",")
		}

		containers = append(containers, ContainerInfo{
			ID:       id,
			Name:     name,
			CName:    cname,
			Interval: interval,
			Ignores:  ignores,
		})
	}

	return containers, nil
}

func getDiffOutput(containerID string) (string, error) {
	cmd := exec.Command("docker", "diff", containerID)
	output, err := cmd.Output()
	if err != nil {
		return "", fmt.Errorf("docker diff failed: %w", err)
	}
	return string(output), nil
}

func main() {
	startServer()
}
