package main

import (
	"encoding/json"
	"flag"
	"fmt"
	"log"
	"net"
	"os"
	"os/signal"
	"path/filepath"
	"strings"
	"syscall"
	"time"

	"golang.org/x/crypto/ssh"

	"github.com/go-git/go-billy/v5/osfs"
	"github.com/go-git/go-git/v5"
	"github.com/go-git/go-git/v5/plumbing"
	"github.com/go-git/go-git/v5/plumbing/cache"
	gitssh "github.com/go-git/go-git/v5/plumbing/transport/ssh"
	"github.com/go-git/go-git/v5/storage/filesystem"
)

var port = flag.Int("port", 3000, "Port to listen on")
var appId = flag.String("app-id", "", "Application ID")
var service = flag.String("service", "", "Service name")
var agentMode = flag.Bool("agent-mode", false, "Sketch agent mode")
var repoAddr = flag.String("repo-addr", "", "Git repository address")
var branch = flag.String("branch", "", "Name of the branch to process")
var rootDir = flag.String("root-dir", "/", "Path to the app code")
var sshKey = flag.String("ssh-key", "", "Private SSH key to access Git repository")
var appDir = flag.String("app-dir", "", "Path to store application repository locally")
var runCfg = flag.String("run-cfg", "", "Run configuration")
var managerAddr = flag.String("manager-addr", "", "Address of the manager")

type Command struct {
	Bin  string   `json:"bin"`
	Args []string `json:"args"`
	Env  []string `json:"env"`
}

type Commit struct {
	Hash    string `json:"hash"`
	Message string `json:"message"`
}

func CloneRepositoryBranch(addr, branch, rootDir string, signer ssh.Signer, path string) (*Commit, error) {
	ref := fmt.Sprintf("refs/heads/%s", branch)
	opts := &git.CloneOptions{
		URL:             addr,
		RemoteName:      "origin",
		ReferenceName:   plumbing.ReferenceName(ref),
		SingleBranch:    true,
		Depth:           1,
		InsecureSkipTLS: true,
		Progress:        os.Stdout,
	}
	if signer != nil {
		opts.Auth = &gitssh.PublicKeys{
			User:   "git",
			Signer: signer,
			HostKeyCallbackHelper: gitssh.HostKeyCallbackHelper{
				HostKeyCallback: func(hostname string, remote net.Addr, key ssh.PublicKey) error {
					// TODO(giolekva): verify server public key
					fmt.Printf("--- %+v\n", ssh.MarshalAuthorizedKey(key))
					return nil
				},
			},
		}
	}
	repo, err := git.Clone(
		filesystem.NewStorage(
			osfs.New(filepath.Join(path, ".git"), osfs.WithBoundOS()),
			cache.NewObjectLRUDefault(),
		),
		osfs.New(path, osfs.WithBoundOS()),
		opts,
	)
	if err != nil {
		return nil, err
	}
	head, err := repo.Head()
	if err != nil {
		return nil, err
	}
	commit, err := repo.CommitObject(head.Hash())
	if err != nil {
		return nil, err
	}
	return &Commit{
		Hash:    head.Hash().String(),
		Message: commit.Message,
	}, nil
}

func readRunConfiguration(p string) []Command {
	r, err := os.Open(p)
	if err != nil {
		panic(err)
	}
	defer r.Close()
	var cmds []Command
	if err := json.NewDecoder(r).Decode(&cmds); err != nil {
		log.Fatal(err)
	}
	return cmds
}

func main() {
	flag.Parse()
	self, ok := os.LookupEnv("SELF_IP")
	if !ok {
		panic("no SELF_IP")
	}
	id, ok := os.LookupEnv("SELF_ID")
	if !ok {
		panic("no SELF_ID")
	}
	var signer ssh.Signer
	// TODO(gio): revisit this logic
	if *sshKey != "" && !(strings.HasPrefix(*repoAddr, "http://") || strings.HasPrefix(*repoAddr, "https://")) {
		key, err := os.ReadFile(*sshKey)
		if err != nil {
			panic(err)
		}
		signer, err = ssh.ParsePrivateKey(key)
		if err != nil {
			panic(err)
		}
	}
	if !*agentMode {
		if err := os.Mkdir(*appDir, os.ModePerm); err != nil {
			panic(err)
		}
	}
	cmds := readRunConfiguration(*runCfg)
	s := NewServer(*agentMode, *port, *appId, *service, id, *repoAddr, *branch, *rootDir, signer, *appDir, cmds, self, *managerAddr)
	go func() {
		if err := s.Start(); err != nil {
			log.Fatal(err)
		} else {
			log.Println("Done")
			os.Exit(0)
		}
	}()
	go func() {
		for {
			time.Sleep(30 * time.Second)
			newCmds := readRunConfiguration(*runCfg)
			if commandsChanged(cmds, newCmds) {
				s.UpdateRunCommands(newCmds)
				cmds = newCmds
			}
		}
	}()
	sigChan := make(chan os.Signal, 1)
	signal.Notify(sigChan, syscall.SIGINT, syscall.SIGTERM)
	<-sigChan
	s.Stop()
}

func commandsChanged(a, b []Command) bool {
	if len(a) != len(b) {
		return true
	}
	for i, x := range a {
		y := b[i]
		if x.Bin != y.Bin {
			return true
		}
		if len(x.Args) != len(y.Args) {
			return true
		}
		for j, k := range x.Args {
			l := y.Args[j]
			if k != l {
				return true
			}
		}
		if !*agentMode {
			if len(x.Env) != len(y.Env) {
				return true
			}
			for j, k := range x.Env {
				l := y.Env[j]
				if k != l {
					return true
				}
			}
		}
	}
	return false
}
