package appmanager

import (
	"errors"
	"fmt"
	"io/ioutil"
	"os"
	"os/exec"
	"path"
	"path/filepath"
	"strings"
	"syscall"

	"github.com/golang/glog"
	"gopkg.in/yaml.v2"
)

type Chart struct {
	Name string `yaml:"name"`
	Type string `yaml:"type"`
}

type HelmChart struct {
	Chart
	chartDir string
	Schema   *Schema
	Triggers *Triggers
	Yamls    []string
}

func HelmChartFromDir(chartDir string) (*HelmChart, error) {
	var chart HelmChart
	chart.chartDir = chartDir
	c, err := ReadChart(path.Join(chartDir, "Chart.yaml"))
	if err != nil {
		return nil, err
	}
	chart.Chart = *c
	schema, err := ReadSchema(path.Join(chartDir, "Schema.yaml"))
	if err != nil && !os.IsNotExist(err) {
		return nil, err
	}
	chart.Schema = schema
	triggers, err := ReadTriggers(path.Join(chartDir, "Triggers.yaml"))
	if err != nil && !os.IsNotExist(err) {
		return nil, err
	}
	chart.Triggers = triggers
	return &chart, nil
}

func HelmChartFromTar(chartTar string) (*HelmChart, error) {
	if !strings.HasSuffix(chartTar, ".tar.gz") {
		return nil, errors.New("Expected .tar.gz file")
	}
	dir := filepath.Dir(chartTar)
	archive := filepath.Base(chartTar)
	if err := syscall.Chdir(dir); err != nil {
		return nil, err
	}
	cmd := exec.Command("tar", "-xvf", archive)
	var stdout strings.Builder
	var stderr strings.Builder
	cmd.Stdout = &stdout
	cmd.Stderr = &stderr
	if err := cmd.Run(); err != nil {
		return nil, errors.New(stderr.String())
	}
	glog.Info(stdout.String())
	glog.Info(dir)
	return HelmChartFromDir(dir)
}

func (h *HelmChart) Install(
	helmBin string,
	values map[string]string) error {
	namespace := fmt.Sprintf("app-%s", h.Chart.Name)
	cmd := generateHelmInstallCmd(helmBin, h.chartDir, namespace, values)
	glog.Info(cmd.String())
	var stdout strings.Builder
	var stderr strings.Builder
	cmd.Stdout = &stdout
	cmd.Stderr = &stderr
	err := cmd.Run()
	if err != nil {
		return errors.New(stderr.String())
	}
	glog.Info(stdout.String())
	return nil
}

func generateHelmInstallCmd(
	helmBin string,
	archive string,
	namespace string,
	values map[string]string) *exec.Cmd {
	cmd := exec.Command(helmBin)
	cmd.Args = append(cmd.Args, "install")
	cmd.Args = append(cmd.Args, fmt.Sprintf("--namespace=%s", namespace))
	cmd.Args = append(cmd.Args, "--generate-name")
	cmd.Args = append(cmd.Args, fmt.Sprintf("%s", archive))
	// TODO(giolekva): validate values
	for key, value := range values {
		cmd.Args = append(cmd.Args, fmt.Sprintf("--set=%s=%s", key, value))
	}
	return cmd
}

func ChartFromYaml(str string) (*Chart, error) {
	var s Chart
	err := yaml.Unmarshal([]byte(str), &s)
	if err != nil {
		return nil, err
	}
	return &s, nil
}

func ReadChart(chartFile string) (*Chart, error) {
	f, err := os.Open(chartFile)
	if err != nil {
		return nil, err
	}
	defer f.Close()
	b, err := ioutil.ReadAll(f)
	if err != nil {
		return nil, err
	}
	return ChartFromYaml(string(b))
}
