package main

import (
	"encoding/json"
	"flag"
	"fmt"
	"log"
	"net"
	"os"
	"strings"

	"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"
	gitssh "github.com/go-git/go-git/v5/plumbing/transport/ssh"
	"github.com/go-git/go-git/v5/storage/memory"
)

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 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(memory.NewStorage(), 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 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 err := os.Mkdir(*appDir, os.ModePerm); err != nil {
		panic(err)
	}
	r, err := os.Open(*runCfg)
	if err != nil {
		panic(err)
	}
	defer r.Close()
	var cmds []Command
	if err := json.NewDecoder(r).Decode(&cmds); err != nil {
		panic(err)
	}
	s := NewServer(*port, *appId, *service, id, *repoAddr, *branch, *rootDir, signer, *appDir, cmds, self, *managerAddr)
	if err := s.Start(); err != nil {
		log.Fatal(err)
	}
}
