package cmd

import (
	"fmt"

	"github.com/FollowTheProcess/gotoil/cli/app"
	"github.com/MakeNowJust/heredoc/v2"
	"github.com/spf13/cobra"
)

func buildCheckoutCmd() *cobra.Command {
	app := app.New()

	checkoutCmd := &cobra.Command{
		Use:   "checkout <project>",
		Args:  cobra.ExactArgs(1),
		Short: "Checkout an existing development project.",
		Long: heredoc.Doc(`
		
		Checkout an existing development project.

		The checkout command lets you easily resume work on an existing project,
		whether that project is available locally in your configured projects directory,
		or if it is on GitHub.

		If gotoil finds your project locally, and you have enabled VSCode in your
		config file, it will open it for you. If not, it will just tell you where
		to find it.

		If your project is on your GitHub, gotoil will clone it for you and then open it
		(or tell you where it is if you haven't got VSCode configured).

		Finally, if checkout can't find a match after searching locally and on GitHub,
		it will report as such and prompt you to use 'gotoil new' to create one.

		If you pass a shorthand to someone elses repo (e.g. 'someoneelse/theirproject')
		gotoil will recognise this repo isn't yours, create a fork for you,
		clone this fork and then either open it for you or show you where to get it
		depending on whether you have set VSCode in your config file.

		Note: Forking happens asynchronously on GitHub's end which means sometimes
		it might take a while for your fork to appear (although normally it's < 2 seconds).
		gotoil waits a short amount of time and checks if your fork is available, if it is
		then the cloning will proceed as normal. If for some reason the forking is taking
		a while, gotoil will exit and inform you what to do next.

		If this happens, most of the time all it needs is few second wait and a
		'gotoil checkout <fork>' to get you on your way.
		`),
		Example: heredoc.Doc(`
		
		# Checkout one of your projects
		$ gotoil checkout myproject

		# Fork 'n' Clone someone elses project
		$ gotoil checkout someoneelse/theirproject
		`),
		PreRunE: func(cmd *cobra.Command, args []string) error {
			return app.Config.Load(cmd) // nolint (wrapcheck)
		},
		RunE: func(cmd *cobra.Command, args []string) error {
			project := args[0]
			if err := app.Checkout(project); err != nil {
				return fmt.Errorf("error checking out %s: %w", project, err)
			}
			return nil
		},
	}

	return checkoutCmd
}
