package storage

import (
	"fmt"
	"github.com/pkg/sftp"
	"golang.org/x/crypto/ssh"
	"sort"
	"time"
)

type SFTP struct {
	Config map[string]string
}

func (f SFTP) ListFiles() ([]File, error) {
	var auths []ssh.AuthMethod
	auths = append(auths, ssh.Password(f.Config["password"]))

	config := ssh.ClientConfig{
		User: f.Config["username"],
		Auth: auths,
		// Auth: []ssh.AuthMethod{
		//  ssh.KeyboardInteractive(SshInteractive),
		// },

		// Uncomment to ignore host key check
		HostKeyCallback: ssh.InsecureIgnoreHostKey(),
		//HostKeyCallback: ssh.FixedHostKey(hostKey),
		// HostKeyCallback: func(hostname string, remote net.Addr, key ssh.PublicKey) error {
		//  return nil
		// },
		Timeout: 30 * time.Second,
	}

	conn, err := ssh.Dial("tcp", f.Config["addr"], &config)
	if err != nil {
		return nil, err
	}

	defer conn.Close()

	sc, err := sftp.NewClient(conn)
	if err != nil {
		return nil, err
	}

	defer sc.Close()

	files, err := sc.ReadDir(f.Config["path"])
	if err != nil {
		return nil, err
	}

	fileList := []File{}

	for _, file := range files {
		if file.IsDir() {
			continue
		}
		generateFile := GeneralFile{
			name: fmt.Sprintf("%v/%v", f.Config["path"], file.Name()),
			time: file.ModTime(),
		}
		fileList = append(fileList, generateFile)
	}

	sort.SliceStable(fileList, func(i, j int) bool {
		t1, _ := fileList[i].GetTime()
		t2, _ := fileList[j].GetTime()
		return t1.Before(t2)
	})

	return fileList, nil
}

func (f SFTP) Delete(files []File) error {
	var auths []ssh.AuthMethod
	auths = append(auths, ssh.Password(f.Config["password"]))

	config := ssh.ClientConfig{
		User: f.Config["username"],
		Auth: auths,
		// Auth: []ssh.AuthMethod{
		//  ssh.KeyboardInteractive(SshInteractive),
		// },

		// Uncomment to ignore host key check
		HostKeyCallback: ssh.InsecureIgnoreHostKey(),
		//HostKeyCallback: ssh.FixedHostKey(hostKey),
		// HostKeyCallback: func(hostname string, remote net.Addr, key ssh.PublicKey) error {
		//  return nil
		// },
		Timeout: 30 * time.Second,
	}

	conn, err := ssh.Dial("tcp", f.Config["addr"], &config)
	if err != nil {
		return err
	}

	defer conn.Close()

	sc, err := sftp.NewClient(conn)
	if err != nil {
		return err
	}

	defer sc.Close()

	for _, f := range files {
		name, err := f.GetName()
		if err != nil {
			return err
		}
		err = sc.Remove(name)
		if err != nil {
			return err
		}
	}

	return nil

}