package installer

import (
	"bytes"
	"encoding/json"
	"errors"
	"fmt"
	"io"
	"io/fs"
	"io/ioutil"
	"net"
	"net/http"
	"os"
	"path"
	"path/filepath"
	"sync"
	"time"

	"github.com/go-git/go-billy/v5/util"
	"github.com/go-git/go-git/v5"
	"github.com/go-git/go-git/v5/plumbing/object"
	gitssh "github.com/go-git/go-git/v5/plumbing/transport/ssh"
	"golang.org/x/crypto/ssh"
	"sigs.k8s.io/yaml"

	"github.com/giolekva/pcloud/core/installer/soft"
)

type RepoIO interface {
	Addr() string
	Pull() error
	ReadConfig() (Config, error)
	ReadAppConfig(path string) (AppConfig, error)
	ReadKustomization(path string) (*Kustomization, error)
	WriteKustomization(path string, kust Kustomization) error
	ReadYaml(path string) (map[string]any, error)
	WriteYaml(path string, data any) error
	CommitAndPush(message string) error
	WriteCommitAndPush(path, contents, message string) error
	Reader(path string) (io.ReadCloser, error)
	Writer(path string) (io.WriteCloser, error)
	CreateDir(path string) error
	RemoveDir(path string) error
	InstallApp(app App, path string, values map[string]any, derived Derived) error
	RemoveApp(path string) error
	FindAllInstances(root string, appId string) ([]AppConfig, error)
	FindInstance(root string, id string) (AppConfig, error)
}

type repoIO struct {
	repo   *soft.Repository
	signer ssh.Signer
	l      sync.Locker
}

func NewRepoIO(repo *soft.Repository, signer ssh.Signer) RepoIO {
	return &repoIO{
		repo,
		signer,
		&sync.Mutex{},
	}
}

func (r *repoIO) Addr() string {
	return r.repo.Addr.Addr
}

func (r *repoIO) Pull() error {
	r.l.Lock()
	defer r.l.Unlock()
	return r.pullWithoutLock()
}

func (r *repoIO) pullWithoutLock() error {
	wt, err := r.repo.Worktree()
	if err != nil {
		fmt.Printf("EEEER wt: %s\b", err)
		return nil
	}
	err = wt.Pull(&git.PullOptions{
		Auth:  auth(r.signer),
		Force: true,
	})
	// TODO(gio): propagate error
	if err != nil {
		fmt.Printf("EEEER: %s\b", err)
	}
	return nil
}

func (r *repoIO) ReadConfig() (Config, error) {
	configF, err := r.Reader(configFileName)
	if err != nil {
		return Config{}, err
	}
	defer configF.Close()
	var cfg Config
	if err := ReadYaml(configF, &cfg); err != nil {
		return Config{}, err
	} else {
		return cfg, nil
	}
}

func (r *repoIO) ReadAppConfig(path string) (AppConfig, error) {
	configF, err := r.Reader(path)
	if err != nil {
		return AppConfig{}, err
	}
	defer configF.Close()
	var cfg AppConfig
	if err := ReadYaml(configF, &cfg); err != nil {
		return AppConfig{}, err
	} else {
		return cfg, nil
	}
}

func (r *repoIO) ReadKustomization(path string) (*Kustomization, error) {
	inp, err := r.Reader(path)
	if err != nil {
		return nil, err
	}
	defer inp.Close()
	return ReadKustomization(inp)
}

func (r *repoIO) Reader(path string) (io.ReadCloser, error) {
	wt, err := r.repo.Worktree()
	if err != nil {
		return nil, err
	}
	return wt.Filesystem.Open(path)
}

func (r *repoIO) Writer(path string) (io.WriteCloser, error) {
	wt, err := r.repo.Worktree()
	if err != nil {
		return nil, err
	}
	if err := wt.Filesystem.MkdirAll(filepath.Dir(path), fs.ModePerm); err != nil {
		return nil, err
	}
	return wt.Filesystem.Create(path)
}

func (r *repoIO) WriteKustomization(path string, kust Kustomization) error {
	out, err := r.Writer(path)
	if err != nil {
		return err
	}
	return kust.Write(out)
}

func (r *repoIO) WriteYaml(path string, data any) error {
	out, err := r.Writer(path)
	if err != nil {
		return err
	}
	serialized, err := yaml.Marshal(data)
	if err != nil {
		return err
	}
	if _, err := out.Write(serialized); err != nil {
		return err
	}
	return nil
}

func (r *repoIO) ReadYaml(path string) (map[string]any, error) {
	inp, err := r.Reader(path)
	if err != nil {
		return nil, err
	}
	data := make(map[string]any)
	if err := ReadYaml(inp, &data); err != nil {
		return nil, err
	}
	return data, err
}

func (r *repoIO) WriteCommitAndPush(path, contents, message string) error {
	w, err := r.Writer(path)
	if err != nil {
		return err
	}
	defer w.Close()
	if _, err := io.WriteString(w, contents); err != nil {
		return err
	}
	return r.CommitAndPush(message)
}

func (r *repoIO) CommitAndPush(message string) error {
	wt, err := r.repo.Worktree()
	if err != nil {
		return err
	}
	if err := wt.AddGlob("*"); err != nil {
		return err
	}
	if _, err := wt.Commit(message, &git.CommitOptions{
		Author: &object.Signature{
			Name: "pcloud-installer",
			When: time.Now(),
		},
	}); err != nil {
		return err
	}
	return r.repo.Push(&git.PushOptions{
		RemoteName: "origin",
		Auth:       auth(r.signer),
	})
}

func (r *repoIO) CreateDir(path string) error {
	wt, err := r.repo.Worktree()
	if err != nil {
		return err
	}
	return wt.Filesystem.MkdirAll(path, fs.ModePerm)
}

func (r *repoIO) RemoveDir(path string) error {
	wt, err := r.repo.Worktree()
	if err != nil {
		return err
	}
	err = util.RemoveAll(wt.Filesystem, path)
	if err == nil || errors.Is(err, fs.ErrNotExist) {
		return nil
	}
	return err
}

type Release struct {
	Namespace string `json:"namespace"`
	RepoAddr  string `json:"repoAddr"`
	AppDir    string `json:"appDir"`
}

type Derived struct {
	Release Release        `json:"release"`
	Global  Values         `json:"global"`
	Values  map[string]any `json:"input"` // TODO(gio): rename to input
}

type AppConfig struct {
	Id      string         `json:"id"`
	AppId   string         `json:"appId"`
	Config  map[string]any `json:"config"`
	Derived Derived        `json:"derived"`
}

func (a AppConfig) Input(schema Schema) map[string]any {
	ret, err := derivedToConfig(a.Derived.Values, schema)
	if err != nil {
		panic(err) // TODO(gio): handle
	}
	return ret
}

type allocatePortReq struct {
	Protocol      string `json:"protocol"`
	SourcePort    int    `json:"sourcePort"`
	TargetService string `json:"targetService"`
	TargetPort    int    `json:"targetPort"`
}

// TODO(gio): most of this logic should move to AppManager
func (r *repoIO) InstallApp(app App, appRootDir string, values map[string]any, derived Derived) error {
	r.l.Lock()
	defer r.l.Unlock()
	if err := r.pullWithoutLock(); err != nil {
		return err
	}
	if !filepath.IsAbs(appRootDir) {
		return fmt.Errorf("Expected absolute path: %s", appRootDir)
	}
	derived.Release.RepoAddr = r.repo.Addr.FullAddress()
	// TODO(gio): maybe client should populate this?
	derived.Release.AppDir = appRootDir
	rendered, err := app.Render(derived)
	if err != nil {
		return err
	}
	for _, p := range rendered.Ports {
		var buf bytes.Buffer
		req := allocatePortReq{
			Protocol:      p.Protocol,
			SourcePort:    p.SourcePort,
			TargetService: p.TargetService,
			TargetPort:    p.TargetPort,
		}
		fmt.Printf("%+v\n", req)
		if err := json.NewEncoder(&buf).Encode(req); err != nil {
			return err
		}
		resp, err := http.Post(p.Allocator, "application/json", &buf)
		if err != nil {
			return err
		}
		if resp.StatusCode != http.StatusOK {
			io.Copy(os.Stdout, resp.Body)
			return fmt.Errorf("Could not allocate port %d, status code: %d", p.SourcePort, resp.StatusCode)
		}
	}
	if err := r.pullWithoutLock(); err != nil {
		return err
	}
	appRootDir = filepath.Clean(appRootDir)
	for p := appRootDir; p != "/"; {
		parent, child := filepath.Split(p)
		kustPath := filepath.Join(parent, "kustomization.yaml")
		kust, err := r.ReadKustomization(kustPath)
		if err != nil {
			if errors.Is(err, fs.ErrNotExist) {
				k := NewKustomization()
				kust = &k
			} else {
				return err
			}
		}
		kust.AddResources(child)
		if err := r.WriteKustomization(kustPath, *kust); err != nil {
			return err
		}
		p = filepath.Clean(parent)
	}
	{
		if err := r.RemoveDir(appRootDir); err != nil {
			return err
		}
		if err := r.CreateDir(appRootDir); err != nil {
			return err
		}
		cfg := AppConfig{
			AppId:   app.Name(),
			Config:  values,
			Derived: derived,
		}
		if err := r.WriteYaml(path.Join(appRootDir, configFileName), cfg); err != nil {
			return err
		}
	}
	{
		appKust := NewKustomization()
		for name, contents := range rendered.Resources {
			appKust.AddResources(name)
			out, err := r.Writer(path.Join(appRootDir, name))
			if err != nil {
				return err
			}
			defer out.Close()
			if _, err := out.Write(contents); err != nil {
				return err
			}
		}
		if err := r.WriteKustomization(path.Join(appRootDir, "kustomization.yaml"), appKust); err != nil {
			return err
		}
	}
	return r.CommitAndPush(fmt.Sprintf("install: %s", app.Name()))
}

func (r *repoIO) RemoveApp(appRootDir string) error {
	r.l.Lock()
	defer r.l.Unlock()
	r.RemoveDir(appRootDir)
	parent, child := filepath.Split(appRootDir)
	kustPath := filepath.Join(parent, "kustomization.yaml")
	kust, err := r.ReadKustomization(kustPath)
	if err != nil {
		return err
	}
	kust.RemoveResources(child)
	r.WriteKustomization(kustPath, *kust)
	return r.CommitAndPush(fmt.Sprintf("uninstall: %s", child))
}

func (r *repoIO) FindAllInstances(root string, name string) ([]AppConfig, error) {
	if !filepath.IsAbs(root) {
		return nil, fmt.Errorf("Expected absolute path: %s", root)
	}
	kust, err := r.ReadKustomization(filepath.Join(root, "kustomization.yaml"))
	if err != nil {
		return nil, err
	}
	ret := make([]AppConfig, 0)
	for _, app := range kust.Resources {
		cfg, err := r.ReadAppConfig(filepath.Join(root, app, "config.yaml"))
		if err != nil {
			return nil, err
		}
		cfg.Id = app
		if cfg.AppId == name {
			ret = append(ret, cfg)
		}
	}
	return ret, nil
}

func (r *repoIO) FindInstance(root string, id string) (AppConfig, error) {
	if !filepath.IsAbs(root) {
		return AppConfig{}, fmt.Errorf("Expected absolute path: %s", root)
	}
	kust, err := r.ReadKustomization(filepath.Join(root, "kustomization.yaml"))
	if err != nil {
		return AppConfig{}, err
	}
	for _, app := range kust.Resources {
		if app == id {
			cfg, err := r.ReadAppConfig(filepath.Join(root, app, "config.yaml"))
			if err != nil {
				return AppConfig{}, err
			}
			cfg.Id = id
			return cfg, nil
		}
	}
	return AppConfig{}, nil
}

func auth(signer ssh.Signer) *gitssh.PublicKeys {
	return &gitssh.PublicKeys{
		Signer: signer,
		HostKeyCallbackHelper: gitssh.HostKeyCallbackHelper{
			HostKeyCallback: func(hostname string, remote net.Addr, key ssh.PublicKey) error {
				// TODO(giolekva): verify server public key
				// fmt.Printf("## %s || %s -- \n", serverPubKey, ssh.MarshalAuthorizedKey(key))
				return nil
			},
		},
	}
}

func ReadYaml[T any](r io.Reader, o *T) error {
	if contents, err := ioutil.ReadAll(r); err != nil {
		return err
	} else {
		return yaml.UnmarshalStrict(contents, o)
	}
}

func deriveValues(values any, schema Schema, networks []Network) (map[string]any, error) {
	ret := make(map[string]any)
	for k, def := range schema.Fields() {
		// TODO(gio): validate that it is map
		v, ok := values.(map[string]any)[k]
		// TODO(gio): if missing use default value
		if !ok {
			if def.Kind() == KindSSHKey {
				key, err := NewECDSASSHKeyPair("tmp")
				if err != nil {
					return nil, err
				}
				ret[k] = map[string]string{
					"public":  string(key.RawAuthorizedKey()),
					"private": string(key.RawPrivateKey()),
				}
			}
			continue
		}
		switch def.Kind() {
		case KindBoolean:
			ret[k] = v
		case KindString:
			ret[k] = v
		case KindInt:
			ret[k] = v
		case KindNetwork:
			n, err := findNetwork(networks, v.(string)) // TODO(giolekva): validate
			if err != nil {
				return nil, err
			}
			ret[k] = n
		case KindAuth:
			r, err := deriveValues(v, AuthSchema, networks)
			if err != nil {
				return nil, err
			}
			ret[k] = r
		case KindSSHKey:
			r, err := deriveValues(v, SSHKeySchema, networks)
			if err != nil {
				return nil, err
			}
			ret[k] = r
		case KindStruct:
			r, err := deriveValues(v, def, networks)
			if err != nil {
				return nil, err
			}
			ret[k] = r
		default:
			return nil, fmt.Errorf("Should not reach!")
		}
	}
	return ret, nil
}

func derivedToConfig(derived map[string]any, schema Schema) (map[string]any, error) {
	ret := make(map[string]any)
	for k, def := range schema.Fields() {
		v, ok := derived[k]
		// TODO(gio): if missing use default value
		if !ok {
			continue
		}
		switch def.Kind() {
		case KindBoolean:
			ret[k] = v
		case KindString:
			ret[k] = v
		case KindInt:
			ret[k] = v
		case KindNetwork:
			vm, ok := v.(map[string]any)
			if !ok {
				return nil, fmt.Errorf("expected map")
			}
			name, ok := vm["name"]
			if !ok {
				return nil, fmt.Errorf("expected network name")
			}
			ret[k] = name
		case KindAuth:
			vm, ok := v.(map[string]any)
			if !ok {
				return nil, fmt.Errorf("expected map")
			}
			r, err := derivedToConfig(vm, AuthSchema)
			if err != nil {
				return nil, err
			}
			ret[k] = r
		case KindSSHKey:
			vm, ok := v.(map[string]any)
			if !ok {
				return nil, fmt.Errorf("expected map")
			}
			r, err := derivedToConfig(vm, SSHKeySchema)
			if err != nil {
				return nil, err
			}
			ret[k] = r
		case KindStruct:
			vm, ok := v.(map[string]any)
			if !ok {
				return nil, fmt.Errorf("expected map")
			}
			r, err := derivedToConfig(vm, def)
			if err != nil {
				return nil, err
			}
			ret[k] = r
		default:
			return nil, fmt.Errorf("Should not reach!")
		}
	}
	return ret, nil
}

func findNetwork(networks []Network, name string) (Network, error) {
	for _, n := range networks {
		if n.Name == name {
			return n, nil
		}
	}
	return Network{}, fmt.Errorf("Network not found: %s", name)
}

type Network struct {
	Name              string `json:"name,omitempty"`
	IngressClass      string `json:"ingressClass,omitempty"`
	CertificateIssuer string `json:"certificateIssuer,omitempty"`
	Domain            string `json:"domain,omitempty"`
	AllocatePortAddr  string `json:"allocatePortAddr,omitempty"`
}
