// Copyright 2022 The ChromiumOS Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// Represents the CLI command grouping
package cli

import (
	common_utils "go.chromium.org/chromiumos/test/provision/v2/common-utils"
	"context"
	"flag"
	"fmt"
	"log"
	"strings"

	"github.com/pkg/errors"

	"go.chromium.org/chromiumos/config/go/longrunning"
	"go.chromium.org/chromiumos/config/go/test/api"
)

const (
	// version is the version info of this command. It is filled in during emerge.
	version             = "<unknown>"
	defaultLogDirectory = "/tmp/cros-fw-provision/"
	defaultPort         = 80
)

// CLI command executed the provisioning as a CLI
type CLICommand struct {
	logFileName string
	log         *log.Logger
	startupFile string
	installFile string
	flagSet     *flag.FlagSet
}

func NewCLICommand() *CLICommand {
	cc := &CLICommand{
		flagSet: flag.NewFlagSet("cli", flag.ContinueOnError),
	}

	cc.flagSet.StringVar(&cc.logFileName, "log-path", defaultLogDirectory, fmt.Sprintf("Path to record execution logs. Default value is %s", defaultLogDirectory))
	cc.flagSet.StringVar(&cc.startupFile, "startup", "", "Specify the StartUp ProvisionStartupRequest jsonproto input file.")
	cc.flagSet.StringVar(&cc.installFile, "install", "", "Specify the Install InstallRequest jsonproto input file.")
	return cc
}

func (cc *CLICommand) Is(group string) bool {
	return strings.HasPrefix(group, "cli")
}

func (cc *CLICommand) Name() string {
	return "cli"
}

func (cc *CLICommand) Init(args []string) error {
	err := cc.flagSet.Parse(args)
	if err != nil {
		return err
	}

	cc.log, err = SetUpLog(cc.logFileName)
	if err != nil {
		return err
	}

	if err = cc.validate(); err != nil {
		return err
	}

	return nil
}

// Logger returns the log
func (cc *CLICommand) Logger() *log.Logger {
	return cc.log
}

// validate checks if inputs are ok
func (cc *CLICommand) validate() error {
	if cc.startupFile == "" {
		return errors.New("startup file not specified, use -startup")
	}

	if cc.installFile == "" {
		return errors.New("install file not specified, use -install")
	}
	return nil
}

// Run starts the firmware provision and does a single provision.
func (cc *CLICommand) Run() error {
	cc.log.Printf("Running CLI Mode (V2) - Firmware Provision:")

	ps, closer, err := NewFWProvisionServer(0, cc.log)
	defer closer()
	if err != nil {
		cc.log.Println("Failed to create provision server: ", err)
		return err
	}

	startupProto, err := common_utils.ParseProvisionStartupRequest(cc.startupFile)
	if err != nil {
		return errors.Wrap(err, "unable to parse ProvisionStartupRequest proto")
	}
	installProto, err := common_utils.ParseInstallRequest(cc.installFile)
	if err != nil {
		return errors.Wrap(err, "unable to parse InstallRequest proto")
	}

	ctx := context.Background()
	startupRes, err := ps.StartUp(ctx, startupProto)
	if err != nil {
		return errors.Wrap(err, "failed to call StartUp")
	}
	cc.log.Printf("StartUp complete - %s", startupRes.String())

	op, err := ps.Install(ctx, installProto)
	if err != nil {
		return errors.Wrap(err, "failed to call Install")
	}
	cc.log.Printf("Install LRO - %s", op.String())
	op, err = ps.manager.WaitOperation(ctx, &longrunning.WaitOperationRequest{
		Name: op.Name,
	})
	if err != nil {
		return errors.Wrap(err, "failed to wait operation")
	}
	cc.log.Printf("Install complete - %s", op.String())
	if !op.Done {
		return errors.Errorf("operation not done: %s", op.String())
	}
	if op.GetError() != nil {
		return errors.Errorf("installed failed: %s", op.GetError().String())
	}
	if op.GetResponse() == nil {
		return errors.Errorf("no response returned: %s", op)
	}
	installResp := new(api.InstallResponse)
	if !op.GetResponse().MessageIs(installResp) {
		return errors.Errorf("unexpected response: %s", op.GetResponse().String())
	}
	if err := op.GetResponse().UnmarshalTo(installResp); err != nil {
		return errors.Wrap(err, "failed to unmarshal response")
	}
	if installResp.Status != api.InstallResponse_STATUS_SUCCESS {
		return errors.Errorf("install failed: %v", installResp.Status)
	}
	return nil
}
