package main

import (
	"bytes"
	"context"
	"encoding/json"
	"flag"
	"fmt"
	"io"
	"log"
	"net/http"
	"os"
	"syscall"

	"github.com/golang/glog"
	"github.com/google/uuid"
	apiv1 "k8s.io/api/core/v1"
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
	"k8s.io/client-go/kubernetes"
	corev1 "k8s.io/client-go/kubernetes/typed/core/v1"
	"k8s.io/client-go/rest"
	"k8s.io/client-go/tools/clientcmd"

	app "github.com/giolekva/pcloud/appmanager"
)

var kubeconfig = flag.String("kubeconfig", "", "Absolute path to the kubeconfig file.")
var helmBin = flag.String("helm_bin", "/usr/local/bin/helm", "Path to the Helm binary.")
var port = flag.Int("port", 1234, "Port to listen on.")
var apiAddr = flag.String("api_addr", "", "PCloud API service address.")
var managerStoreFile = flag.String("manager_store_file", "", "Persistent file containing installed application information.")

var helmUploadPage = `
<html>
<head>
       <title>Upload Helm chart</title>
</head>
<body>
<form enctype="multipart/form-data" method="post">
    <input type="file" name="chartfile" />
    <input type="submit" value="upload" />
</form>
</body>
</html>
`

type handler struct {
	manager  *app.Manager
	nsClient corev1.NamespaceInterface
}

func (hn *handler) handleInstall(w http.ResponseWriter, r *http.Request) {
	if r.Method == "GET" {
		_, err := io.WriteString(w, helmUploadPage)
		if err != nil {
			http.Error(w, err.Error(), http.StatusInternalServerError)
		}
	} else if r.Method == "POST" {
		r.ParseMultipartForm(1000000)
		file, handler, err := r.FormFile("chartfile")
		if err != nil {
			http.Error(w, err.Error(), http.StatusInternalServerError)
			return
		}
		defer file.Close()
		tmp := uuid.New().String()
		if tmp == "" {
			http.Error(w, "Could not generate temp dir", http.StatusInternalServerError)
			return
		}
		p := "/tmp/" + tmp
		// TODO(giolekva): defer rmdir
		if err := syscall.Mkdir(p, 0777); err != nil {
			http.Error(w, "Could not create temp dir", http.StatusInternalServerError)
			return
		}
		p += "/" + handler.Filename
		f, err := os.OpenFile(p, os.O_WRONLY|os.O_CREATE, 0666)
		if err != nil {
			fmt.Println(err)
			return
		}
		defer f.Close()
		_, err = io.Copy(f, file)
		if err != nil {
			http.Error(w, err.Error(), http.StatusInternalServerError)
			return
		}
		if err = hn.installHelmChart(p); err != nil {
			http.Error(w, err.Error(), http.StatusInternalServerError)
			return
		}
		w.Write([]byte("Installed"))
	}
}

type trigger struct {
	Namespace string `json:"namespace"`
	Template  string `json:"template"`
}

func (hn *handler) handleTriggers(w http.ResponseWriter, r *http.Request) {
	if r.Method != "GET" {
		http.Error(w, "Only GET method is supported on /triggers", http.StatusBadRequest)
		return
	}
	if err := r.ParseForm(); err != nil {
		http.Error(w, err.Error(), http.StatusBadRequest)
		return
	}
	// TODO(giolekva): check if exists
	triggerOnType := r.Form["trigger_on_type"][0]
	triggerOnEvent := r.Form["trigger_on_event"][0]
	var triggers []trigger
	for _, a := range hn.manager.Apps {
		if a.Triggers == nil {
			continue
		}
		for _, t := range a.Triggers.Triggers {
			if t.TriggerOn.Type == triggerOnType && t.TriggerOn.Event == triggerOnEvent {
				triggers = append(triggers, trigger{a.Namespace, t.Template})
			}
		}
	}
	respBody, err := json.Marshal(triggers)
	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}
	if _, err := io.Copy(w, bytes.NewReader(respBody)); err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}
}

func (hn *handler) installHelmChart(path string) error {
	h, err := app.HelmChartFromTar(path)
	if err != nil {
		return err
	}
	if err = app.InstallSchema(h.Schema, *apiAddr); err != nil {
		return err
	}
	glog.Infof("Installed schema: %s", h.Schema)
	namespace := fmt.Sprintf("app-%s", h.Name)
	if err = createNamespace(hn.nsClient, namespace); err != nil {
		return err
	}
	glog.Infof("Created namespaces: %s", namespace)
	if h.Type == "application" {
		if err = h.Install(
			*helmBin,
			map[string]string{}); err != nil {
			return err
		}
		glog.Info("Deployed")
	} else {
		glog.Info("Skipping deployment as we got library chart.")
	}
	hn.manager.Apps[h.Name] = app.App{namespace, h.Triggers}
	app.StoreManagerStateToFile(hn.manager, *managerStoreFile)
	glog.Info("Installed")
	return nil
}

func createNamespace(nsClient corev1.NamespaceInterface, name string) error {
	_, err := nsClient.Create(
		context.TODO(),
		&apiv1.Namespace{
			ObjectMeta: metav1.ObjectMeta{
				Name: name}},
		metav1.CreateOptions{})
	return err
}

func getKubeConfig() (*rest.Config, error) {
	if *kubeconfig != "" {
		return clientcmd.BuildConfigFromFlags("", *kubeconfig)
	} else {
		return rest.InClusterConfig()
	}
}

func main() {
	flag.Parse()
	config, err := getKubeConfig()
	if err != nil {
		glog.Fatalf("Could not initialize Kubeconfig: %v", err)
	}
	clientset, err := kubernetes.NewForConfig(config)
	if err != nil {
		glog.Fatalf("Could not create Kubernetes API client: %v", err)
	}
	namespaces := clientset.CoreV1().Namespaces()
	manager, err := app.LoadManagerStateFromFile(*managerStoreFile)
	if err != nil {
		glog.Fatalf("Could ot initialize manager: %v", err)
	}
	h := handler{manager, namespaces}
	http.HandleFunc("/triggers", h.handleTriggers)
	http.HandleFunc("/", h.handleInstall)
	log.Fatal(http.ListenAndServe(fmt.Sprintf(":%d", *port), nil))

}
