//go:build full

package main

import (
	"fmt"
	"os"
	"path"
	"path/filepath"

	"github.com/tg123/sshpiper/libplugin"
	"github.com/urfave/cli/v2"

	"github.com/tg123/sshpiper/plugin/internal/workingdir"

	log "github.com/sirupsen/logrus"
)

func main() {

	libplugin.CreateAndRunPluginTemplate(&libplugin.PluginTemplate{
		Name:  "workingdir",
		Usage: "sshpiperd workingdir plugin",
		Flags: []cli.Flag{
			&cli.StringFlag{
				Name:    "root",
				Usage:   "path to root working directory",
				Value:   "/var/sshpiper",
				EnvVars: []string{"SSHPIPERD_WORKINGDIR_ROOT"},
			},
			&cli.BoolFlag{
				Name:    "allow-baduser-name",
				Usage:   "allow bad username",
				EnvVars: []string{"SSHPIPERD_WORKINGDIR_ALLOWBADUSERNAME"},
			},
			&cli.BoolFlag{
				Name:    "no-check-perm",
				Usage:   "disable 0400 checking",
				EnvVars: []string{"SSHPIPERD_WORKINGDIR_NOCHECKPERM"},
			},
			&cli.BoolFlag{
				Name:    "strict-hostkey",
				Usage:   "upstream host public key must be in known_hosts file, otherwise drop the connection",
				EnvVars: []string{"SSHPIPERD_WORKINGDIR_STRICTHOSTKEY"},
			},
		},
		CreateConfig: func(c *cli.Context) (*libplugin.SshPiperPluginConfig, error) {

			root := c.String("root")

			return &libplugin.SshPiperPluginConfig{
				PublicKeyCallback: func(conn libplugin.ConnMetadata, key []byte) (*libplugin.Upstream, error) {

					userdir := path.Join(root, conn.User())

					var upstream *libplugin.Upstream

					_ = filepath.Walk(userdir, func(path string, info os.FileInfo, err error) error {

						log.Infof("search public key in path: %v", path)
						if err != nil {
							log.Infof("error walking path: %v", err)
							return nil
						}

						if !info.IsDir() {
							return nil
						}

						w := &workingdir.Workingdir{
							Path:        path,
							NoCheckPerm: c.Bool("no-check-perm"),
							Strict:      false,
						}

						u, err := w.CreateUpstream()
						if err != nil {
							return nil
						}

						k, err := w.Mapkey(key)
						if err != nil {
							return nil
						}

						u.Auth = libplugin.CreatePrivateKeyAuth(k)
						upstream = u
						return fmt.Errorf("stop")
					})

					if upstream != nil {
						return upstream, nil
					}

					return nil, fmt.Errorf("no matching public key found in %v", userdir)
				},
			}, nil
		},
	})
}
