package main

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

type deployReq struct {
	State  any            `json:"state"`
	Config map[string]any `json:"config"`
}

type req struct {
	Id            string         `json:"id"`
	SSHPrivateKey string         `json:"sshPrivateKey"`
	Config        map[string]any `json:"config"`
}

const publicKey = `ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIPK58vMu0MwIzdZT+mqpIBkhl48p9+/YwDCZv7MgTesF`
const privateKey = `-----BEGIN OPENSSH PRIVATE KEY-----
b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAAMwAAAAtzc2gtZW
QyNTUxOQAAACDyufLzLtDMCM3WU/pqqSAZIZePKffv2MAwmb+zIE3rBQAAAKA42oIlONqC
JQAAAAtzc2gtZWQyNTUxOQAAACDyufLzLtDMCM3WU/pqqSAZIZePKffv2MAwmb+zIE3rBQ
AAAEC2CdpXtaFfqA8/mqjf9uITU1mrPOI4CeWgiQFEefFW1/K58vMu0MwIzdZT+mqpIBkh
l48p9+/YwDCZv7MgTesFAAAAGXJvb3RAY2FudmFzYnVpbGRlci1tYXN0ZXIBAgME
-----END OPENSSH PRIVATE KEY-----`

func handleSave(w http.ResponseWriter, r *http.Request) {
	var state map[string]any
	if err := json.NewDecoder(r.Body).Decode(&state); err != nil {
		panic(err)
	}
	out, err := os.Create("/tmp/state.json")
	if err != nil {
		panic(err)
	}
	defer out.Close()
	if err := json.NewEncoder(out).Encode(state); err != nil {
		panic(err)
	}
}

func handleSavedGet(w http.ResponseWriter, r *http.Request) {
	inp, err := os.Open("/tmp/state.json")
	if err != nil {
		panic(err)
	}
	defer inp.Close()
	io.Copy(w, inp)
}

func handleDeploy(w http.ResponseWriter, r *http.Request) {
	var dr deployReq
	if err := json.NewDecoder(r.Body).Decode(&dr); err != nil {
		http.Error(w, err.Error(), http.StatusBadRequest)
		return
	}
	req := req{
		Id:            "test",
		SSHPrivateKey: privateKey,
		Config:        dr.Config,
	}
	var buf bytes.Buffer
	if err := json.NewEncoder(&buf).Encode(req); err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}
	resp, err := http.Post("http://appmanager.hgrz-appmanager.svc.cluster.local/api/dodo-app", "application/json", &buf)
	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}
	var b bytes.Buffer
	io.Copy(&b, resp.Body)
	if resp.StatusCode != http.StatusOK {
		http.Error(w, b.String(), http.StatusInternalServerError)
		return
	}
}

type Network struct {
	Name   string `json:"name"`
	Domain string `json:"domain"`
}

type envResp struct {
	DeployKey string    `json:"deployKey"`
	Networks  []Network `json:"networks"`
}

func handleEnv(w http.ResponseWriter, r *http.Request) {
	resp := envResp{
		DeployKey: publicKey,
		Networks: []Network{{
			Name:   "Public",
			Domain: "v1.dodo.cloud",
		}, {
			Name:   "Private",
			Domain: "p.v1.dodo.cloud",
		}},
	}
	fmt.Println(resp)
	json.NewEncoder(w).Encode(resp)
}

func getPort() string {
	if p, ok := os.LookupEnv("DODO_PORT_WEB"); ok {
		return p
	}
	panic("port missing")
}

func main() {
	port := getPort()
	http.HandleFunc("GET /saved", handleSavedGet)
	http.HandleFunc("POST /saved", handleSave)
	http.HandleFunc("GET /env", handleEnv)
	http.HandleFunc("POST /deploy", handleDeploy)
	http.Handle("/", http.FileServer(http.Dir("./front")))
	log.Fatal(http.ListenAndServe(fmt.Sprintf(":%s", port), nil))
}
