/*
 Copyright 2015 Runtime Inc.
 Licensed under the Apache License, Version 2.0 (the "License");
 you may not use this file except in compliance with the License.
 You may obtain a copy of the License at

 http://www.apache.org/licenses/LICENSE-2.0

 Unless required by applicable law or agreed to in writing, software
 distributed under the License is distributed on an "AS IS" BASIS,
 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 See the License for the specific language governing permissions and
 limitations under the License.
*/

package main

import (
	"fmt"
	"github.com/mynewt/newt/cli"
	"github.com/spf13/cobra"
	"log"
	"os"
	"path/filepath"
	"strings"
)

var ExitOnFailure bool = false
var ExportAll bool = false
var ImportAll bool = false
var NewtVersion string = "1.0"
var NewtRepo *cli.Repo
var NewtLogLevel string = ""
var NewtNest *cli.Nest

func NewtUsage(cmd *cobra.Command, err error) {
	if err != nil {
		sErr := err.(*cli.NewtError)
		log.Printf("[DEBUG] %s", sErr.StackTrace)
		fmt.Println("Error: ", sErr.Text)
	}

	if cmd != nil {
		cmd.Usage()
	}
	os.Exit(1)
}

func targetSetCmd(cmd *cobra.Command, args []string) {
	if len(args) != 2 {
		NewtUsage(cmd,
			cli.NewNewtError("Must specify two arguments (sect & k=v) to set"))
	}

	t, err := cli.LoadTarget(NewtRepo, args[0])
	if err != nil {
		NewtUsage(cmd, err)
	}
	ar := strings.Split(args[1], "=")

	t.Vars[ar[0]] = ar[1]

	if err := t.Save(); err != nil {
		NewtUsage(cmd, err)
	}

	fmt.Printf("Target %s successfully set %s to %s\n", args[0],
		ar[0], ar[1])
}

func targetUnsetCmd(cmd *cobra.Command, args []string) {
	if len(args) != 2 {
		NewtUsage(cmd,
			cli.NewNewtError("Must specify two arguments (sect & k) to unset"))
	}

	t, err := cli.LoadTarget(NewtRepo, args[0])
	if err != nil {
		NewtUsage(cmd, err)
	}

	if err := t.DeleteVar(args[1]); err != nil {
		NewtUsage(cmd, err)
	}

	fmt.Printf("Target %s successfully unset %s\n", args[0], args[1])
}

func targetShowCmd(cmd *cobra.Command, args []string) {
	dispSect := ""
	if len(args) == 1 {
		dispSect = args[0]
	}

	targets, err := cli.GetTargets(NewtRepo)
	if err != nil {
		NewtUsage(cmd, err)
	}

	for _, target := range targets {
		if dispSect == "" || dispSect == target.Vars["name"] {
			fmt.Println(target.Vars["name"])
			vars := target.GetVars()
			for k, v := range vars {
				fmt.Printf("	%s: %s\n", k, v)
			}
		}
	}
}

func targetCreateCmd(cmd *cobra.Command, args []string) {
	if len(args) != 1 {
		NewtUsage(cmd, cli.NewNewtError("Wrong number of args to create cmd."))
	}

	fmt.Println("Creating target " + args[0])

	if cli.TargetExists(NewtRepo, args[0]) {
		NewtUsage(cmd, cli.NewNewtError(
			"Target already exists, cannot create target with same name."))
	}

	target := &cli.Target{
		Repo: NewtRepo,
		Vars: map[string]string{},
	}
	target.Vars["name"] = args[0]

	err := target.Save()
	if err != nil {
		fmt.Println(err)
	} else {
		fmt.Printf("Target %s sucessfully created!\n", args[0])
	}
}

func targetBuildCmd(cmd *cobra.Command, args []string) {
	if len(args) < 1 {
		NewtUsage(cmd, cli.NewNewtError("Must specify target to build"))
	}

	t, err := cli.LoadTarget(NewtRepo, args[0])
	if err != nil {
		NewtUsage(cmd, err)
	}

	if len(args) > 1 && args[1] == "clean" {
		if len(args) > 2 && args[2] == "all" {
			err = t.BuildClean(true)
		} else {
			err = t.BuildClean(false)
		}
	} else {
		err = t.Build()
	}

	if err != nil {
		NewtUsage(cmd, err)
	} else {
		fmt.Println("Successfully run!")
	}
}

func targetDelCmd(cmd *cobra.Command, args []string) {
	if len(args) < 1 {
		NewtUsage(cmd, cli.NewNewtError("Must specify target to delete"))
	}

	t, err := cli.LoadTarget(NewtRepo, args[0])
	if err != nil {
		NewtUsage(cmd, err)
	}

	if err := t.Remove(); err != nil {
		NewtUsage(cmd, err)
	}

	fmt.Printf("Target %s successfully removed\n", args[0])
}

func targetTestCmd(cmd *cobra.Command, args []string) {
	if len(args) < 1 {
		NewtUsage(cmd, cli.NewNewtError("Must specify target to build"))
	}

	t, err := cli.LoadTarget(NewtRepo, args[0])
	if err != nil {
		NewtUsage(cmd, err)
	}

	if len(args) > 1 && args[1] == "clean" {
		if len(args) > 2 && args[2] == "all" {
			err = t.Test("testclean", true)
		} else {
			err = t.Test("testclean", false)
		}
	} else {
		err = t.Test("test", ExitOnFailure)
	}

	if err != nil {
		NewtUsage(cmd, err)
	} else {
		fmt.Println("Successfully run!")
	}
}

func targetExportCmd(cmd *cobra.Command, args []string) {
	var targetName string
	if ExportAll {
		targetName = ""
	} else {
		if len(args) < 1 {
			NewtUsage(cmd, cli.NewNewtError("Must either specify -a flag or name of "+
				"target to export"))
		}
		targetName = args[0]
	}

	err := cli.ExportTargets(NewtRepo, targetName, ExportAll, os.Stdout)
	if err != nil {
		NewtUsage(cmd, err)
	}
}

func targetImportCmd(cmd *cobra.Command, args []string) {
	var targetName string
	if ImportAll {
		targetName = ""
	} else {
		if len(args) < 1 {
			NewtUsage(cmd, cli.NewNewtError("Must either specify -a flag or name of "+
				"target to import"))
		}

		targetName = args[0]
	}

	err := cli.ImportTargets(NewtRepo, targetName, ImportAll, os.Stdin)
	if err != nil {
		NewtUsage(cmd, err)
	}

	fmt.Println("Target(s) successfully imported!")
}

func targetAddCmds(base *cobra.Command) {
	targetCmd := &cobra.Command{
		Use:   "target",
		Short: "Set and view target information",
		PersistentPreRun: func(cmd *cobra.Command, args []string) {
			cli.Init(NewtLogLevel)

			var err error
			NewtRepo, err = cli.NewRepo()
			if err != nil {
				NewtUsage(nil, err)
			}
		},
		Run: func(cmd *cobra.Command, args []string) {
			cmd.Usage()
		},
	}

	setCmd := &cobra.Command{
		Use:   "set",
		Short: "Set target configuration variable",
		Run:   targetSetCmd,
	}

	targetCmd.AddCommand(setCmd)

	unsetCmd := &cobra.Command{
		Use:   "unset",
		Short: "Unset target configuration variable",
		Run:   targetUnsetCmd,
	}

	targetCmd.AddCommand(unsetCmd)

	delCmd := &cobra.Command{
		Use:   "delete",
		Short: "Delete target",
		Run:   targetDelCmd,
	}

	targetCmd.AddCommand(delCmd)

	createCmd := &cobra.Command{
		Use:   "create",
		Short: "Create a target",
		Run:   targetCreateCmd,
	}

	targetCmd.AddCommand(createCmd)

	showCmd := &cobra.Command{
		Use:   "show",
		Short: "View target configuration variables",
		Run:   targetShowCmd,
	}

	targetCmd.AddCommand(showCmd)

	buildCmd := &cobra.Command{
		Use:   "build",
		Short: "Build target",
		Run:   targetBuildCmd,
	}

	targetCmd.AddCommand(buildCmd)

	testCmd := &cobra.Command{
		Use:   "test",
		Short: "Test target",
		Run:   targetTestCmd,
	}

	targetCmd.AddCommand(testCmd)

	exportCmd := &cobra.Command{
		Use:   "export",
		Short: "Export target",
		Run:   targetExportCmd,
	}

	exportCmd.PersistentFlags().BoolVarP(&ExportAll, "export-all", "a", false,
		"If present, export all targets")

	targetCmd.AddCommand(exportCmd)

	importCmd := &cobra.Command{
		Use:   "import",
		Short: "Import target",
		Run:   targetImportCmd,
	}

	importCmd.PersistentFlags().BoolVarP(&ImportAll, "import-all", "a", false,
		"If present, import all targets")

	targetCmd.AddCommand(importCmd)

	base.AddCommand(targetCmd)
}

func repoCreateCmd(cmd *cobra.Command, args []string) {
	// must specify a repo name to create
	if len(args) != 1 {
		NewtUsage(cmd, cli.NewNewtError("Must specify a repo name to repo create"))
	}

	cwd, err := os.Getwd()
	if err != nil {
		NewtUsage(cmd, err)
	}

	_, err = cli.CreateRepo(cwd, args[0])
	if err != nil {
		NewtUsage(cmd, err)
	}

	fmt.Println("Repo " + args[0] + " successfully created!")
}

func repoAddCmds(baseCmd *cobra.Command) {
	repoCmd := &cobra.Command{
		Use:   "repo",
		Short: "Commands to manipulate the base repository",
		Run: func(cmd *cobra.Command, args []string) {
			cmd.Usage()
		},
	}

	createCmd := &cobra.Command{
		Use:   "create",
		Short: "Create a repository",
		Run:   repoCreateCmd,
	}

	repoCmd.AddCommand(createCmd)

	baseCmd.AddCommand(repoCmd)
}

func dispEgg(egg *cli.Egg) error {
	fmt.Printf("Egg %s, version %s\n", egg.FullName, egg.Version)
	fmt.Printf("  path: %s\n", filepath.Clean(egg.BasePath))
	if egg.Capabilities != nil {
		fmt.Printf("  capabilities: ")
		caps, err := egg.GetCapabilities()
		if err != nil {
			return err
		}
		for _, capability := range caps {
			fmt.Printf("%s ", capability)
		}
		fmt.Printf("\n")
	}
	if len(egg.Deps) > 0 {
		fmt.Printf("  deps: ")
		for _, dep := range egg.Deps {
			if dep == nil {
				continue
			}
			fmt.Printf("%s ", dep)
		}
		fmt.Printf("\n")
	}

	if egg.LinkerScript != "" {
		fmt.Printf("  linkerscript: %s\n", egg.LinkerScript)
	}
	return nil
}

func eggListCmd(cmd *cobra.Command, args []string) {
	eggMgr, err := cli.NewEggMgr(NewtRepo, nil)
	if err != nil {
		NewtUsage(cmd, err)
	}

	for _, egg := range eggMgr.Eggs {
		if err := dispEgg(egg); err != nil {
			NewtUsage(cmd, err)
		}
	}
}

func eggCheckDepsCmd(cmd *cobra.Command, args []string) {
	eggMgr, err := cli.NewEggMgr(NewtRepo, nil)
	if err != nil {
		NewtUsage(cmd, err)
	}

	if err := eggMgr.CheckDeps(); err != nil {
		NewtUsage(cmd, err)
	}

	fmt.Println("Dependencies successfully resolved!")
}

func eggAddCmds(baseCmd *cobra.Command) {
	eggCmd := &cobra.Command{
		Use:   "egg",
		Short: "Commands to list and inspect eggs on a repo",
		PersistentPreRun: func(cmd *cobra.Command, args []string) {
			cli.Init(NewtLogLevel)

			var err error
			NewtRepo, err = cli.NewRepo()
			if err != nil {
				NewtUsage(nil, err)
			}
		},
		Run: func(cmd *cobra.Command, args []string) {
			NewtUsage(cmd, nil)
		},
	}

	listCmd := &cobra.Command{
		Use:   "list",
		Short: "List eggs in the current repository",
		Run:   eggListCmd,
	}

	eggCmd.AddCommand(listCmd)

	checkDepsCmd := &cobra.Command{
		Use:   "checkdeps",
		Short: "Check egg dependencies",
		Run:   eggCheckDepsCmd,
	}

	eggCmd.AddCommand(checkDepsCmd)

	baseCmd.AddCommand(eggCmd)
}

func nestLayCmd(cmd *cobra.Command, args []string) {
	if len(args) != 2 {
		NewtUsage(cmd,
			cli.NewNewtError("Must specify name and URL to lay clutch file"))
	}

	clutchName := args[0]
	clutchUrl := args[1]

	clutch, err := cli.NewClutch(NewtNest)
	if err != nil {
		NewtUsage(cmd, err)
	}
	clutch.Name = clutchName
	clutch.RemoteUrl = clutchUrl

	eggMgr, err := cli.NewEggMgr(NewtRepo, nil)
	if err != nil {
		NewtUsage(cmd, err)
	}

	if err := clutch.LoadFromPM(eggMgr); err != nil {
		NewtUsage(cmd, err)
	}

	clutchStr, err := clutch.Serialize()
	if err != nil {
		NewtUsage(cmd, err)
	}

	fmt.Print(clutchStr)
}

func nestGetCmd(cmd *cobra.Command, args []string) {
	if len(args) != 2 {
		NewtUsage(cmd,
			cli.NewNewtError("Must specify both name and URL to larva install command"))
	}

	name := args[0]
	url := args[1]

	clutch, err := cli.NewClutch(NewtNest)
	if err != nil {
		NewtUsage(cmd, err)
	}

	if err := clutch.Install(name, url); err != nil {
		NewtUsage(cmd, err)
	}

	fmt.Println("Clutch " + name + " sucessfully installed to Nest.")
}

func nestShowCmd(cmd *cobra.Command, args []string) {
	clutches, err := NewtNest.GetClutches()
	if err != nil {
		NewtUsage(cmd, err)
	}

	for name, clutch := range clutches {
		fmt.Printf("Remote clutch %s (eggshells: %d)\n", name, len(clutch.EggShells))
	}
}

func nestAddCmds(baseCmd *cobra.Command) {
	nestCmd := &cobra.Command{
		Use:   "nest",
		Short: "Commands to manage nests & clutches (remote egg repositories)",
		PersistentPreRun: func(cmd *cobra.Command, args []string) {
			cli.Init(NewtLogLevel)

			var err error
			NewtRepo, err = cli.NewRepo()
			if err != nil {
				NewtUsage(nil, err)
			}

			NewtNest, err = cli.NewNest(NewtRepo)
			if err != nil {
				NewtUsage(nil, err)
			}
		},
		Run: func(cmd *cobra.Command, args []string) {
			NewtUsage(cmd, nil)
		},
	}

	layCmd := &cobra.Command{
		Use:   "lay",
		Short: "Lay (generate) a clutch file from the eggs in the current directory",
		Run:   nestLayCmd,
	}

	nestCmd.AddCommand(layCmd)

	getCmd := &cobra.Command{
		Use:   "get",
		Short: "Get a remote clutch, and put it in the current nest",
		Run:   nestGetCmd,
	}

	nestCmd.AddCommand(getCmd)

	showCmd := &cobra.Command{
		Use:   "show",
		Short: "Show the clutches installed in the current nest",
		Run:   nestShowCmd,
	}

	nestCmd.AddCommand(showCmd)

	baseCmd.AddCommand(nestCmd)
}

func parseCmds() *cobra.Command {
	newtCmd := &cobra.Command{
		Use:   "newt",
		Short: "Newt is a tool to help you compose and build your own OS",
		Long: `Newt allows you to create your own embedded project based on the
		     Newt operating system`,
		Run: func(cmd *cobra.Command, args []string) {
			cmd.Usage()
		},
	}

	newtCmd.PersistentFlags().StringVarP(&NewtLogLevel, "loglevel", "l",
		"WARN", "Log level, defaults to WARN.")

	versCmd := &cobra.Command{
		Use:   "version",
		Short: "Print the Newt version number",
		Run: func(cmd *cobra.Command, args []string) {
			fmt.Println("Newt version: ", NewtVersion)
		},
	}

	newtCmd.AddCommand(versCmd)

	targetAddCmds(newtCmd)
	repoAddCmds(newtCmd)
	eggAddCmds(newtCmd)
	nestAddCmds(newtCmd)

	return newtCmd
}

func main() {
	cmd := parseCmds()
	cmd.Execute()
}
