package main

import (
	"context"
	"flag"
	"log"
	"net/http"
	"os"
	"path/filepath"

	"git.xeserv.us/xena/route/internal/gluaroute"
	"github.com/Xe/eclier"
	"github.com/Xe/gluanetrc"
	"github.com/Xe/x/tools/glue/libs/gluaexpect"
	"github.com/Xe/x/tools/glue/libs/gluasimplebox"
	"github.com/ailncode/gluaxmlpath"
	"github.com/cjoudrey/gluahttp"
	"github.com/cjoudrey/gluaurl"
	"github.com/kohkimakimoto/gluaenv"
	"github.com/kohkimakimoto/gluafs"
	"github.com/kohkimakimoto/gluaquestion"
	"github.com/kohkimakimoto/gluassh"
	"github.com/kohkimakimoto/gluatemplate"
	"github.com/kohkimakimoto/gluayaml"
	homedir "github.com/mitchellh/go-homedir"
	"github.com/otm/gluaflag"
	"github.com/otm/gluash"
	"github.com/yuin/gluare"
	lua "github.com/yuin/gopher-lua"
	json "layeh.com/gopher-json"
)

var hDir string
var cfgHome *string
var netrcFile *string
var defaultServer *string

func init() {
	dir, err := homedir.Dir()
	if err != nil {
		log.Fatal(err)
	}

	hDir = dir

	cfgHome = flag.String("home", filepath.Join(hDir, ".construct"), "construct's home directory")
	netrcFile = flag.String("netrc", filepath.Join(hDir, ".netrc"), "location of netrc file to use for authentication")
	defaultServer = flag.String("default-server", "https://api.route.xeserv.us:7268", "api server to connect to")
}

func main() {
	flag.Parse()

	ctx, cancel := context.WithCancel(context.Background())
	defer cancel()

	pluginLoc := filepath.Join(*cfgHome, "plugins")
	scriptsLoc := filepath.Join(*cfgHome, "local", "scripts")

	os.MkdirAll(pluginLoc, 0755)
	os.MkdirAll(scriptsLoc, 0755)

	if _, err := os.Stat(*netrcFile); err != nil {
		log.Printf("creating netrc file...")
		fout, err := os.Create(*netrcFile)
		if err != nil {
			log.Fatal(err)
		}
		fout.Close()
	}

	opts := []eclier.RouterOption{
		eclier.WithGluaCreationHook(preload),
		eclier.WithScriptHome(scriptsLoc),
	}

	err := filepath.Walk(pluginLoc, func(path string, info os.FileInfo, err error) error {
		if info.IsDir() {
			opts = append(opts, eclier.WithScriptHome(info.Name()))
		}

		return nil
	})
	if err != nil {
		log.Fatal(err)
	}

	r, err := eclier.NewRouter(opts...)
	if err != nil {
		log.Fatal(err)
	}

	r.Run(ctx, flag.Args())
}

func preload(L *lua.LState) {
	L.PreloadModule("re", gluare.Loader)
	L.PreloadModule("sh", gluash.Loader)
	L.PreloadModule("fs", gluafs.Loader)
	L.PreloadModule("env", gluaenv.Loader)
	L.PreloadModule("yaml", gluayaml.Loader)
	L.PreloadModule("question", gluaquestion.Loader)
	L.PreloadModule("ssh", gluassh.Loader)
	L.PreloadModule("http", gluahttp.NewHttpModule(&http.Client{}).Loader)
	L.PreloadModule("flag", gluaflag.Loader)
	L.PreloadModule("template", gluatemplate.Loader)
	L.PreloadModule("url", gluaurl.Loader)
	gluaexpect.Preload(L)
	gluasimplebox.Preload(L)
	gluaxmlpath.Preload(L)
	json.Preload(L)
	gluanetrc.Preload(L)
	gluaroute.Preload(L)
}
