package dockerimg

import (
	"bufio"
	"crypto/rand"
	"crypto/rsa"
	"crypto/x509"
	"encoding/pem"
	"fmt"
	"os"
	"path/filepath"
	"strings"

	"github.com/kevinburke/ssh_config"
	"golang.org/x/crypto/ssh"
	"golang.org/x/crypto/ssh/knownhosts"
)

const keyBitSize = 2048

// SSHTheater does the necessary key pair generation, known_hosts updates, ssh_config file updates etc steps
// so that ssh can connect to a locally running sketch container to other local processes like vscode without
// the user having to run the usual ssh obstacle course.
//
// SSHTheater does not modify your default .ssh/config, or known_hosts files.  However, in order for you
// to be able to use it properly you will have to make a one-time edit to your ~/.ssh/config file.
//
// In your ~/.ssh/config file, add the following line:
//
// Include $HOME/.sketch/ssh_config
//
// where $HOME is your home directory.
type SSHTheater struct {
	cntrName string
	sshHost  string
	sshPort  string

	knownHostsPath     string
	userIdentityPath   string
	sshConfigPath      string
	serverIdentityPath string

	serverPublicKey ssh.PublicKey
	serverIdentity  []byte
	userIdentity    []byte
}

// NewSSHTheather will set up everything so that you can use ssh on localhost to connect to
// the sketch container.  Call #Clean when you are done with the container to remove the
// various entries it created in its known_hosts and ssh_config files. Also note that
// this will generate key pairs for both the ssh server identity and the user identity, if
// these files do not already exist.  These key pair files are not deleted by #Cleanup,
// so they can be re-used across invocations of sketch. This means every sketch container
// that runs on this host will use the same ssh server identity.
//
// If this doesn't return an error, you should be able to run "ssh <cntrName>"
// in a terminal on your host machine to open a shell into the container without having
// to manually accept changes to your known_hosts file etc.
func NewSSHTheather(cntrName, sshHost, sshPort string) (*SSHTheater, error) {
	base := filepath.Join(os.Getenv("HOME"), ".sketch")
	if _, err := os.Stat(base); err != nil {
		if err := os.Mkdir(base, 0o777); err != nil {
			return nil, fmt.Errorf("couldn't create %s: %w", base, err)
		}
	}

	cst := &SSHTheater{
		cntrName:           cntrName,
		sshHost:            sshHost,
		sshPort:            sshPort,
		knownHostsPath:     filepath.Join(base, "known_hosts"),
		userIdentityPath:   filepath.Join(base, "container_user_identity"),
		serverIdentityPath: filepath.Join(base, "container_server_identity"),
		sshConfigPath:      filepath.Join(base, "ssh_config"),
	}
	if _, err := createKeyPairIfMissing(cst.serverIdentityPath); err != nil {
		return nil, fmt.Errorf("couldn't create server identity: %w", err)
	}
	if _, err := createKeyPairIfMissing(cst.userIdentityPath); err != nil {
		return nil, fmt.Errorf("couldn't create user identity: %w", err)
	}

	serverIdentity, err := os.ReadFile(cst.serverIdentityPath)
	if err != nil {
		return nil, fmt.Errorf("couldn't read container's ssh server identity: %w", err)
	}
	cst.serverIdentity = serverIdentity

	serverPubKeyBytes, err := os.ReadFile(cst.serverIdentityPath + ".pub")
	serverPubKey, _, _, _, err := ssh.ParseAuthorizedKey(serverPubKeyBytes)
	if err != nil {
		return nil, fmt.Errorf("couldn't read ssh server public key: %w", err)
	}
	cst.serverPublicKey = serverPubKey

	userIdentity, err := os.ReadFile(cst.userIdentityPath + ".pub")
	if err != nil {
		return nil, fmt.Errorf("couldn't read ssh user identity: %w", err)
	}
	cst.userIdentity = userIdentity

	if err := cst.addContainerToSSHConfig(); err != nil {
		return nil, fmt.Errorf("couldn't add container to ssh_config: %w", err)
	}

	if err := cst.addContainerToKnownHosts(); err != nil {
		return nil, fmt.Errorf("couldn't update known hosts: %w", err)
	}

	return cst, nil
}

func CheckForInclude() error {
	sketchSSHPathInclude := "Include " + filepath.Join(os.Getenv("HOME"), ".sketch", "ssh_config")
	defaultSSHPath := filepath.Join(os.Getenv("HOME"), ".ssh", "config")
	f, _ := os.Open(filepath.Join(os.Getenv("HOME"), ".ssh", "config"))
	cfg, _ := ssh_config.Decode(f)
	var sketchInludePos *ssh_config.Position
	var firstNonIncludePos *ssh_config.Position
	for _, host := range cfg.Hosts {
		for _, node := range host.Nodes {
			inc, ok := node.(*ssh_config.Include)
			if ok {
				if strings.TrimSpace(inc.String()) == sketchSSHPathInclude {
					pos := inc.Pos()
					sketchInludePos = &pos
				}
			} else if firstNonIncludePos == nil && !strings.HasPrefix(strings.TrimSpace(node.String()), "#") {
				pos := node.Pos()
				firstNonIncludePos = &pos
			}
		}
	}

	if sketchInludePos == nil {
		return fmt.Errorf("⚠️ SSH connections are disabled. To enable them, add the line %q to the top of %s before any 'Host' lines", sketchSSHPathInclude, defaultSSHPath)
	}

	if firstNonIncludePos != nil && firstNonIncludePos.Line < sketchInludePos.Line {
		fmt.Printf("⚠️ SSH confg warning: The location of the Include statement for sketch's ssh config on line %d of %s may prevent ssh from working with sketch containers. Try moving it to the top of the file (before any 'Host' lines) if ssh isn't working for you.\n", sketchInludePos.Line, defaultSSHPath)
	}
	return nil
}

func removeFromHosts(cntrName string, cfgHosts []*ssh_config.Host) []*ssh_config.Host {
	hosts := []*ssh_config.Host{}
	for _, host := range cfgHosts {
		if host.Matches(cntrName) || strings.Contains(host.String(), cntrName) {
			continue
		}
		patMatch := false
		for _, pat := range host.Patterns {
			if strings.Contains(pat.String(), cntrName) {
				patMatch = true
			}
		}
		if patMatch {
			continue
		}

		hosts = append(hosts, host)
	}
	return hosts
}

func generatePrivateKey(bitSize int) (*rsa.PrivateKey, error) {
	privateKey, err := rsa.GenerateKey(rand.Reader, bitSize)
	if err != nil {
		return nil, err
	}
	return privateKey, nil
}

// generatePublicKey take a rsa.PublicKey and return bytes suitable for writing to .pub file
// returns in the format "ssh-rsa ..."
func generatePublicKey(privatekey *rsa.PublicKey) (ssh.PublicKey, error) {
	publicRsaKey, err := ssh.NewPublicKey(privatekey)
	if err != nil {
		return nil, err
	}

	return publicRsaKey, nil
}

func encodePrivateKeyToPEM(privateKey *rsa.PrivateKey) []byte {
	pemBlock := &pem.Block{
		Type:  "RSA PRIVATE KEY",
		Bytes: x509.MarshalPKCS1PrivateKey(privateKey),
	}
	pemBytes := pem.EncodeToMemory(pemBlock)
	return pemBytes
}

func writeKeyToFile(keyBytes []byte, filename string) error {
	err := os.WriteFile(filename, keyBytes, 0o600)
	return err
}

func createKeyPairIfMissing(idPath string) (ssh.PublicKey, error) {
	if _, err := os.Stat(idPath); err == nil {
		return nil, nil
	}

	privateKey, err := generatePrivateKey(keyBitSize)
	if err != nil {
		return nil, fmt.Errorf("Error generating private key: %w", err)
	}

	publicRsaKey, err := generatePublicKey(&privateKey.PublicKey)
	if err != nil {
		return nil, fmt.Errorf("Error generating public key: %w", err)
	}

	privateKeyPEM := encodePrivateKeyToPEM(privateKey)

	err = writeKeyToFile(privateKeyPEM, idPath)
	if err != nil {
		return nil, fmt.Errorf("Error writing private key to file %w", err)
	}
	pubKeyBytes := ssh.MarshalAuthorizedKey(publicRsaKey)

	err = writeKeyToFile([]byte(pubKeyBytes), idPath+".pub")
	if err != nil {
		return nil, fmt.Errorf("Error writing public key to file %w", err)
	}
	return publicRsaKey, nil
}

func (c *SSHTheater) addSketchHostMatchIfMissing(cfg *ssh_config.Config) error {
	found := false
	for _, host := range cfg.Hosts {
		if strings.Contains(host.String(), "host=\"sketch-*\"") {
			found = true
			break
		}
	}
	if !found {
		hostPattern, err := ssh_config.NewPattern("host=\"sketch-*\"")
		if err != nil {
			return fmt.Errorf("couldn't add pattern to ssh_config: %w", err)
		}

		hostCfg := &ssh_config.Host{Patterns: []*ssh_config.Pattern{hostPattern}}
		hostCfg.Nodes = append(hostCfg.Nodes, &ssh_config.KV{Key: "UserKnownHostsFile", Value: c.knownHostsPath})

		hostCfg.Nodes = append(hostCfg.Nodes, &ssh_config.KV{Key: "IdentityFile", Value: c.userIdentityPath})
		hostCfg.Nodes = append(hostCfg.Nodes, &ssh_config.Empty{})

		cfg.Hosts = append([]*ssh_config.Host{hostCfg}, cfg.Hosts...)
	}
	return nil
}

func (c *SSHTheater) addContainerToSSHConfig() error {
	f, err := os.OpenFile(c.sshConfigPath, os.O_RDWR|os.O_CREATE, 0o644)
	if err != nil {
		return fmt.Errorf("couldn't open ssh_config: %w", err)
	}
	defer f.Close()

	cfg, err := ssh_config.Decode(f)
	if err != nil {
		return fmt.Errorf("couldn't decode ssh_config: %w", err)
	}
	cntrPattern, err := ssh_config.NewPattern(c.cntrName)
	if err != nil {
		return fmt.Errorf("couldn't add pattern to ssh_config: %w", err)
	}

	// Remove any matches for this container if they already exist.
	cfg.Hosts = removeFromHosts(c.cntrName, cfg.Hosts)

	hostCfg := &ssh_config.Host{Patterns: []*ssh_config.Pattern{cntrPattern}}
	hostCfg.Nodes = append(hostCfg.Nodes, &ssh_config.KV{Key: "HostName", Value: c.sshHost})
	hostCfg.Nodes = append(hostCfg.Nodes, &ssh_config.KV{Key: "User", Value: "root"})
	hostCfg.Nodes = append(hostCfg.Nodes, &ssh_config.KV{Key: "Port", Value: c.sshPort})
	hostCfg.Nodes = append(hostCfg.Nodes, &ssh_config.KV{Key: "IdentityFile", Value: c.userIdentityPath})
	hostCfg.Nodes = append(hostCfg.Nodes, &ssh_config.KV{Key: "UserKnownHostsFile", Value: c.knownHostsPath})

	hostCfg.Nodes = append(hostCfg.Nodes, &ssh_config.Empty{})
	cfg.Hosts = append(cfg.Hosts, hostCfg)

	if err := c.addSketchHostMatchIfMissing(cfg); err != nil {
		return fmt.Errorf("couldn't add missing host match: %w", err)
	}

	cfgBytes, err := cfg.MarshalText()
	if err != nil {
		return fmt.Errorf("couldn't marshal ssh_config: %w", err)
	}
	if err := f.Truncate(0); err != nil {
		return fmt.Errorf("couldn't truncate ssh_config: %w", err)
	}
	if _, err := f.Seek(0, 0); err != nil {
		return fmt.Errorf("couldn't seek to beginning of ssh_config: %w", err)
	}
	if _, err := f.Write(cfgBytes); err != nil {
		return fmt.Errorf("couldn't write ssh_config: %w", err)
	}

	return nil
}

func (c *SSHTheater) addContainerToKnownHosts() error {
	f, err := os.OpenFile(c.knownHostsPath, os.O_RDWR|os.O_CREATE, 0o644)
	if err != nil {
		return fmt.Errorf("couldn't open %s: %w", c.knownHostsPath, err)
	}
	defer f.Close()
	pkBytes := c.serverPublicKey.Marshal()
	if len(pkBytes) == 0 {
		return fmt.Errorf("empty serverPublicKey. This is a bug")
	}
	newHostLine := knownhosts.Line([]string{c.sshHost + ":" + c.sshPort}, c.serverPublicKey)

	outputLines := []string{}
	scanner := bufio.NewScanner(f)
	for scanner.Scan() {
		outputLines = append(outputLines, scanner.Text())
	}
	outputLines = append(outputLines, newHostLine)
	if err := f.Truncate(0); err != nil {
		return fmt.Errorf("couldn't truncate known_hosts: %w", err)
	}
	if _, err := f.Seek(0, 0); err != nil {
		return fmt.Errorf("couldn't seek to beginning of known_hosts: %w", err)
	}
	if _, err := f.Write([]byte(strings.Join(outputLines, "\n"))); err != nil {
		return fmt.Errorf("couldn't write updated known_hosts to to %s: %w", c.knownHostsPath, err)
	}

	return nil
}

func (c *SSHTheater) removeContainerFromKnownHosts() error {
	f, err := os.OpenFile(c.knownHostsPath, os.O_RDWR|os.O_CREATE, 0o644)
	if err != nil {
		return fmt.Errorf("couldn't open ssh_config: %w", err)
	}
	defer f.Close()
	scanner := bufio.NewScanner(f)
	lineToRemove := knownhosts.Line([]string{c.sshHost + ":" + c.sshPort}, c.serverPublicKey)
	outputLines := []string{}
	for scanner.Scan() {
		if scanner.Text() == lineToRemove {
			continue
		}
		outputLines = append(outputLines, scanner.Text())
	}
	if err := f.Truncate(0); err != nil {
		return fmt.Errorf("couldn't truncate known_hosts: %w", err)
	}
	if _, err := f.Seek(0, 0); err != nil {
		return fmt.Errorf("couldn't seek to beginning of known_hosts: %w", err)
	}
	if _, err := f.Write([]byte(strings.Join(outputLines, "\n"))); err != nil {
		return fmt.Errorf("couldn't write updated known_hosts to to %s: %w", c.knownHostsPath, err)
	}

	return nil
}

func (c *SSHTheater) Cleanup() error {
	if err := c.removeContainerFromSSHConfig(); err != nil {
		return fmt.Errorf("couldn't remove container from ssh_config: %v\n", err)
	}
	if err := c.removeContainerFromKnownHosts(); err != nil {
		return fmt.Errorf("couldn't remove container from ssh_config: %v\n", err)
	}

	return nil
}

func (c *SSHTheater) removeContainerFromSSHConfig() error {
	f, err := os.OpenFile(c.sshConfigPath, os.O_RDWR|os.O_CREATE, 0o644)
	if err != nil {
		return fmt.Errorf("couldn't open ssh_config: %w", err)
	}
	defer f.Close()

	cfg, err := ssh_config.Decode(f)
	if err != nil {
		return fmt.Errorf("couldn't decode ssh_config: %w", err)
	}
	cfg.Hosts = removeFromHosts(c.cntrName, cfg.Hosts)

	if err := c.addSketchHostMatchIfMissing(cfg); err != nil {
		return fmt.Errorf("couldn't add missing host match: %w", err)
	}

	cfgBytes, err := cfg.MarshalText()
	if err != nil {
		return fmt.Errorf("couldn't marshal ssh_config: %w", err)
	}
	if err := f.Truncate(0); err != nil {
		return fmt.Errorf("couldn't truncate ssh_config: %w", err)
	}
	if _, err := f.Seek(0, 0); err != nil {
		return fmt.Errorf("couldn't seek to beginning of ssh_config: %w", err)
	}
	if _, err := f.Write(cfgBytes); err != nil {
		return fmt.Errorf("couldn't write ssh_config: %w", err)
	}
	return nil
}
