// -
//   ========================LICENSE_START=================================
//   O-RAN-SC
//   %%
//   Copyright (C) 2022: Nordix Foundation
//   %%
//   Licensed under the Apache License, Version 2.0 (the "License");
//   you may not use this file except in compliance with the License.
//   You may obtain a copy of the License at
//
//        http://www.apache.org/licenses/LICENSE-2.0
//
//   Unless required by applicable law or agreed to in writing, software
//   distributed under the License is distributed on an "AS IS" BASIS,
//   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//   See the License for the specific language governing permissions and
//   limitations under the License.
//   ========================LICENSE_END===================================
//

package main

import (
	"context"
	"database/sql"
	"encoding/json"
	"flag"
	"fmt"
	"github.com/pkg/errors"
	"gopkg.in/yaml.v2"
	"helm.sh/helm/v3/pkg/action"
	"helm.sh/helm/v3/pkg/chart"
	"helm.sh/helm/v3/pkg/chart/loader"
	"helm.sh/helm/v3/pkg/cli"
	"helm.sh/helm/v3/pkg/getter"
	"helm.sh/helm/v3/pkg/kube"
	"helm.sh/helm/v3/pkg/repo"
	"io/ioutil"
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
	"k8s.io/cli-runtime/pkg/genericclioptions"
	kubernetes "k8s.io/client-go/kubernetes"
	"k8s.io/client-go/rest"
	"net/http"
	"os"
	"path/filepath"
)

var settings *cli.EnvSettings
var chartRequested *chart.Chart

//var url string
var repoName string
var chartName string
var releaseName string
var namespace string

type ChartInfo struct {
	Name       string                 `json:",omitempty"`
	Namespace  string                 `json:",omitempty"`
	Revision   int                    `json:",omitempty"`
	Updated    string                 `json:",omitempty"`
	Status     string                 `json:",omitempty"`
	Chart      string                 `json:",omitempty"`
	AppVersion string                 `json:",omitempty"`
	Values     map[string]interface{} `json:"-"`
}

type Rapp struct {
	Type            string
	SecurityEnabled bool
	Realm           string
	Client          string
	Roles           []struct {
		Role   string
		Grants []string
	}
	Apps []struct {
		Prefix  string
		Methods []string
	}
}

var rapp Rapp

const (
	host     = "postgres.default"
	port     = 5432
	user     = "capif"
	password = "capif"
	dbname   = "capif"
)

func runInstall(res http.ResponseWriter, req *http.Request) {
	query := req.URL.Query()
	chartName = query.Get("chart")
	releaseName = chartName
	fmt.Println("Installing ", chartName)

	var msg string
	var chart string
	var install *action.Install
	chartMuseumService, chartMuseumPort := findService("chartmuseum", "default")
	fmt.Printf("Chart Museum service:%s, Port:%d\n", chartMuseumService, chartMuseumPort)
	url := "http://" + chartMuseumService + ":" + fmt.Sprint(chartMuseumPort)
	if !chartInstalled(chartName) {
		// Add repo
		fmt.Printf("Adding %s to Helm Repo\n", url)
		_, err := addToRepo(url)
		if err != nil {
			msg = err.Error()
		} else {
			install, err = dryRun()
			if err != nil {
				msg = err.Error()
			} else {
				if rapp.SecurityEnabled && rapp.Type == "provider" {
					// keycloak client setup
					fmt.Println("Setting up keycloak")
					_, err = http.Get("http://rapps-keycloak-mgr.default/create?realm=" + rapp.Realm + "&name=" + rapp.Client + "&role=" + rapp.Roles[0].Role)
					if err != nil {
						msg = err.Error()
					} else {
						fmt.Println("Setting up istio")
						_, err := http.Get("http://rapps-istio-mgr.default/create?name=" + chartName + "&realm=" + rapp.Realm + "&role=" + rapp.Roles[0].Role + "&method=" + rapp.Roles[0].Grants[0])
						if err != nil {
							msg = err.Error()
						} else {
							// Install chart
							fmt.Printf("Installing chart %s to %s namespace\n", chartName, namespace)
							chart, err = installHelmChart(install)
							if err != nil {
								msg = "Error occurred during installation " + err.Error()
							} else {
								msg = "Successfully installed release: " + chart
							}
						}
					}
				} else {
					// Install chart
					fmt.Printf("Installing chart %s to %s namespace\n", chartName, namespace)
					chart, err = installHelmChart(install)
					if err != nil {
						msg = "Error occurred during installation " + err.Error()
					} else {
						msg = "Successfully installed release: " + chart
					}
				}

			}
		}
		registrerRapp(chartName, rapp.Type)
	} else {
		msg = chartName + " has already been installed"
	}

	// create response binary data
	data := []byte(msg) // slice of bytes
	// write `data` to response
	res.Write(data)
}

func runUninstall(res http.ResponseWriter, req *http.Request) {
	query := req.URL.Query()
	chartName = query.Get("chart")
	releaseName = chartName
	fmt.Println("Uninstalling ", chartName)

	var msg string
	var chart string
	if chartInstalled(chartName) {
		err := getChartValues(chartName)
		if err != nil {
			msg = err.Error()
		} else {
			chart, err = uninstallHelmChart(chartName)
			if err != nil {
				msg = "Error occurred during uninstall " + err.Error()
			} else {
				msg = "Successfully uninstalled release: " + chart
			}
			if rapp.SecurityEnabled && rapp.Type == "provider" {
				// Remove istio objects for rapp
				fmt.Println("Removing istio services")
				_, err := http.Get("http://rapps-istio-mgr.default/remove?name=" + chartName)
				if err != nil {
					msg = err.Error()
				}
				// remove keycloak client
				fmt.Println("Removing keycloak client")
				_, err = http.Get("http://rapps-keycloak-mgr.default/remove?realm=" + rapp.Realm + "&name=" + rapp.Client + "&role=" + rapp.Roles[0].Role)
				if err != nil {
					msg = err.Error()
				}
			}
		}
		unregistrerRapp(chartName, rapp.Type)
	} else {
		msg = chartName + " is not installed"
	}

	// create response binary data
	data := []byte(msg) // slice of bytes
	// write `data` to response
	res.Write(data)
}

func runList(res http.ResponseWriter, req *http.Request) {
	chartInfo := list()
	// create response binary data
	data, err := json.Marshal(chartInfo)
	if err != nil {
		fmt.Printf("Error happened in JSON marshal. Err: %s\n", err)
	}
	// write `data` to response
	res.Write(data)
}

func main() {
	//flag.StringVar(&url, "url", "http://chartmuseum:8080", "ChartMuseum url")
	flag.StringVar(&repoName, "repoName", "local-dev", "Repository name")
	flag.StringVar(&namespace, "namespace", "istio-nonrtric", "namespace for install")
	flag.Parse()
	settings = cli.New()

	runInstallHandler := http.HandlerFunc(runInstall)
	http.Handle("/install", runInstallHandler)
	runUninstallHandler := http.HandlerFunc(runUninstall)
	http.Handle("/uninstall", runUninstallHandler)
	runListHandler := http.HandlerFunc(runList)
	http.Handle("/list", runListHandler)
	http.ListenAndServe(":9000", nil)
}

func addToRepo(url string) (string, error) {
	repoFile := settings.RepositoryConfig

	//Ensure the file directory exists as it is required for file locking
	err := os.MkdirAll(filepath.Dir(repoFile), os.ModePerm)
	if err != nil && !os.IsExist(err) {
		return "", err
	}

	b, err := ioutil.ReadFile(repoFile)
	if err != nil && !os.IsNotExist(err) {
		return "", err
	}

	var f repo.File
	if err := yaml.Unmarshal(b, &f); err != nil {
		return "", err
	}

	if f.Has(repoName) {
		fmt.Printf("repository name (%s) already exists\n", repoName)
		return "", nil
	}

	c := repo.Entry{
		Name: repoName,
		URL:  url,
	}

	r, err := repo.NewChartRepository(&c, getter.All(settings))
	if err != nil {
		return "", err
	}

	if _, err := r.DownloadIndexFile(); err != nil {
		err := errors.Wrapf(err, "looks like %q is not a valid chart repository or cannot be reached", url)
		return "", err
	}

	f.Update(&c)

	if err := f.WriteFile(repoFile, 0644); err != nil {
		return "", err
	}
	fmt.Printf("%q has been added to your repositories\n", repoName)
	return "", nil
}

func dryRun() (*action.Install, error) {
	actionConfig, err := getActionConfig(namespace)

	install := action.NewInstall(actionConfig)

	cp, err := install.ChartPathOptions.LocateChart(fmt.Sprintf("%s/%s", repoName, chartName), settings)

	chartRequested, err = loader.Load(cp)

	install.Namespace = namespace
	install.ReleaseName = releaseName
	install.DryRun = true
	rel, err := install.Run(chartRequested, nil)
	if err != nil {
		fmt.Println(err)
		return install, err
	}

	rappMap := rel.Chart.Values["rapp"]
	// Convert map to json string
	jsonStr, err := json.Marshal(rappMap)
	if err != nil {
		fmt.Println(err)
		return install, err
	}

	if err := json.Unmarshal(jsonStr, &rapp); err != nil {
		fmt.Println(err)
		return install, err
	}
	fmt.Printf("Keycloak key/value pairs in values.yaml - Realm: %s Client: %s Client Role: %s\n", rapp.Realm, rapp.Client, rapp.Roles)
	return install, nil
}

func installHelmChart(install *action.Install) (string, error) {

	install.DryRun = false
	rel, err := install.Run(chartRequested, nil)
	if err != nil {
		fmt.Println(err)
	}
	fmt.Println("Successfully installed release: ", rel.Name)

	return rel.Name, err
}

func getActionConfig(namespace string) (*action.Configuration, error) {
	actionConfig := new(action.Configuration)
	// Create the rest config instance with ServiceAccount values loaded in them
	config, err := rest.InClusterConfig()
	if err != nil {
		// fallback to kubeconfig
		home, exists := os.LookupEnv("HOME")
		if !exists {
			home = "/root"
		}
		kubeconfigPath := filepath.Join(home, ".kube", "config")
		if envvar := os.Getenv("KUBECONFIG"); len(envvar) > 0 {
			kubeconfigPath = envvar
		}
		if err := actionConfig.Init(kube.GetConfig(kubeconfigPath, "", namespace), namespace, os.Getenv("HELM_DRIVER"),
			func(format string, v ...interface{}) {
				fmt.Sprintf(format, v)
			}); err != nil {
			fmt.Println(err)
		}
	} else {
		// Create the ConfigFlags struct instance with initialized values from ServiceAccount
		var kubeConfig *genericclioptions.ConfigFlags
		kubeConfig = genericclioptions.NewConfigFlags(false)
		kubeConfig.APIServer = &config.Host
		kubeConfig.BearerToken = &config.BearerToken
		kubeConfig.CAFile = &config.CAFile
		kubeConfig.Namespace = &namespace
		if err := actionConfig.Init(kubeConfig, namespace, os.Getenv("HELM_DRIVER"), func(format string, v ...interface{}) {
			fmt.Sprintf(format, v)
		}); err != nil {
			fmt.Println(err)
		}
	}
	return actionConfig, err
}

func uninstallHelmChart(name string) (string, error) {
	actionConfig, err := getActionConfig(namespace)
	if err != nil {
		fmt.Println(err)
	}

	iCli := action.NewUninstall(actionConfig)

	resp, err := iCli.Run(name)
	if err != nil {
		fmt.Println(err)
	}
	fmt.Println("Successfully uninstalled release: ", resp.Release.Name)
	return resp.Release.Name, err
}

func connectToK8s() *kubernetes.Clientset {
	config, err := rest.InClusterConfig()
	if err != nil {
		fmt.Println("failed to create K8s config")
	}

	clientset, err := kubernetes.NewForConfig(config)
	if err != nil {
		fmt.Println("Failed to create K8s clientset")
	}

	return clientset
}

func findService(serviceName, namespace string) (string, int32) {
	clientset := connectToK8s()
	svc, err := clientset.CoreV1().Services(namespace).Get(context.TODO(), serviceName, metav1.GetOptions{})
	if err != nil {
		fmt.Println(err.Error())
	}
	return svc.Name, svc.Spec.Ports[0].Port
}

func list() []ChartInfo {
	var charts = []ChartInfo{}
	var chart ChartInfo
	actionConfig, err := getActionConfig(namespace)
	if err != nil {
		panic(err)
	}

	listAction := action.NewList(actionConfig)
	releases, err := listAction.Run()
	if err != nil {
		fmt.Println(err)
	}
	for _, release := range releases {
		//fmt.Println("Release: " + release.Name + " Status: " + release.Info.Status.String())
		chart.Name = release.Name
		chart.Namespace = release.Namespace
		chart.Revision = release.Version
		chart.Updated = release.Info.LastDeployed.String()
		chart.Status = release.Info.Status.String()
		chart.Chart = release.Chart.Metadata.Name + "-" + release.Chart.Metadata.Version
		chart.AppVersion = release.Chart.Metadata.AppVersion
		chart.Values = release.Chart.Values
		charts = append(charts, chart)
	}
	return charts
}

func chartInstalled(chartName string) bool {
	charts := list()
	for _, chart := range charts {
		if chart.Name == chartName {
			return true
		}
	}
	return false
}

func getChartValues(chartName string) error {
	charts := list()
	for _, chart := range charts {
		if chart.Name == chartName {
			rappMap := chart.Values["rapp"]
			fmt.Println("rappMap:", rappMap)
			// Convert map to json string
			jsonStr, err := json.Marshal(rappMap)
			if err != nil {
				fmt.Println("Error:", err)
				return err
			}

			if err := json.Unmarshal(jsonStr, &rapp); err != nil {
				fmt.Println("Error:", err)
				return err
			}
			return nil
		}
	}
	return errors.New("Chart: cannot retrieve values")
}

func registrerRapp(chartName, chartType string) {
	psqlconn := fmt.Sprintf("host=%s port=%d user=%s password=%s dbname=%s sslmode=disable", host, port, user, password, dbname)

	db, err := sql.Open("postgres", psqlconn)
	if err != nil {
		fmt.Println(err)
	} else {
		fmt.Println("Connected!")
	}

	defer db.Close()

	// create
	// hardcoded
	createStmt := `CREATE TABLE IF NOT EXISTS services (
	id serial PRIMARY KEY,
	name VARCHAR ( 50 ) UNIQUE NOT NULL,
	type VARCHAR ( 50 ) NOT NULL,
	created_on TIMESTAMP DEFAULT NOW() 
        );`
	_, err = db.Exec(createStmt)
	if err != nil {
		fmt.Println(err)
	} else {
		fmt.Println("Created table for service registry")
	}

	// dynamic
	insertDynStmt := `insert into "services"("name", "type") values($1, $2)`
	_, err = db.Exec(insertDynStmt, chartName, chartType)
	if err != nil {
		fmt.Println(err)
	} else {
		fmt.Println("Inserted " + chartName + " into service registry")
	}
}

func unregistrerRapp(chartName, chartType string) {
	psqlconn := fmt.Sprintf("host=%s port=%d user=%s password=%s dbname=%s sslmode=disable", host, port, user, password, dbname)

	db, err := sql.Open("postgres", psqlconn)
	if err != nil {
		fmt.Println(err)
	} else {
		fmt.Println("Connected!")
	}

	defer db.Close()

	// dynamic
	deleteDynStmt := `delete from services where name=$1 and type=$2`
	_, err = db.Exec(deleteDynStmt, chartName, chartType)
	if err != nil {
		fmt.Println(err)
	} else {
		fmt.Println("Deleted " + chartName + " from service registry")
	}
}
