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

// Package main implements the cros-servod for starting/stopping servod daemon
// and sending commands to it to control and test DUTs via servo hardware by
// simulating user actions such as power on/off, flashing of firmware/OS,
// screen close, etc.
package main

import (
	"context"
	"flag"
	"fmt"
	"io"
	"log"
	"os"
	"path/filepath"
	"strings"
	"time"

	"go.chromium.org/chromiumos/test/servod/cmd/commandexecutor"
	"go.chromium.org/chromiumos/test/servod/cmd/model"
	"go.chromium.org/chromiumos/test/servod/cmd/servodserver"

	"go.chromium.org/luci/common/errors"
)

const (
	// version is the version info of this command. It is filled in during emerge.
	version         = "<unknown>"
	helpDescription = `cros-servod tool

The tool provides the ability to start/stop a servod Docker container either on the same host or a remote servo host and execute servod commands on it.
go/cros-servod-design to learn more about the design.

Commands:
  cli       Runs the server in CLI mode, executes one of the subcommands (start_servod, stop_servod, exec_cmd, call_servod) by using the input parameters and prints the result to the output file.
            Usage:
            To start servod:
            cros-servod cli start_servod --servo_host_path <ip:port> --servod_docker_container_name <a_unique_name> --servod_docker_image_path <servod_docker_image_path> --servod_port <servod_port> --board <board> --model <model> --serial_name <serial_name> --debug <debug> --recovery_mode <recovery_mode> --config <config> --allow_dual_v4 <allow_dual_v4> [--log_path /tmp/servod/]
            Example (Start non-containerized servod):
            cros-servod cli start_servod --servo_host_path localhost:9876 --servod_port 9901 --board dedede --model galith --serial_name G1911050826
            Example (Start containerized servod):
            cros-servod cli start_servod --servo_host_path localhost:9876 --servod_docker_container_name servod_container1 --servod_docker_image_path gcr.io/chromeos-bot/servod@sha256:2d25f6313c7bbac349607 --servod_port 9901 --board dedede --model galith --serial_name G1911050826

            To stop servod:
            cros-servod cli stop_servod --servo_host_path <ip:port> --servod_docker_container_name <a_unique_name> --servod_port <servod_port> [--log_path /tmp/servod/]
            Example (Stop non-containerized servod):
            cros-servod cli stop_servod --servo_host_path localhost:9876 --servod_port 9901
            Example (Stop containerized servod):
            cros-servod cli stop_servod --servo_host_path localhost:9876 --servod_docker_container_name servod_container1 --servod_port 9901

            To execute command:
            cros-servod cli exec_cmd --servo_host_path <ip:port> --servod_docker_container_name <a_unique_name> --command <command> [--log_path /tmp/servod/]
            Example (Execute fake disconnect command on non-containerized servod):
            cros-servod cli exec_cmd --servo_host_path localhost:9876 --command "dut-control -p 9901 servo_v4_uart_cmd:'fakedisconnect 130 2400'"
            Example (Execute system command on containerized servod):
            cros-servod cli exec_cmd --servo_host_path localhost:9876 --servod_docker_container_name servod_container1 --command "ps -ef | grep servod"

            To call servod for doc:
            cros-servod cli call_servod --servo_host_path <ip:port> --servod_docker_container_name <a_unique_name> --method doc --args <args> [--log_path /tmp/servod/]
            Example (Call DOC method for lid_open control on non-containerized servod):
            cros-servod cli call_servod --servo_host_path localhost:9876 --method doc --args lid_open

            To call servod for get:
            cros-servod cli call_servod --servo_host_path <ip:port> --servod_docker_container_name <a_unique_name> --method get --args <args> [--log_path /tmp/servod/]
            Example (Call GET method for lid_open control on non-containerized servod):
            cros-servod cli call_servod --servo_host_path localhost:9876 --method get --args lid_open

            To call servod for set:
            cros-servod cli call_servod --servo_host_path <ip:port> --servod_docker_container_name <a_unique_name> --method set --args <args> [--log_path /tmp/servod/]
            Example (Call SET method to set lid_open control value to yes on containerized servod):
            cros-servod cli call_servod --servo_host_path localhost:9876 --servod_docker_container_name servod_container1 --method set --args "lid_open:yes"
            Example (Call SET method to execute fake disconnect on non-containerized servod):
            cros-servod cli call_servod --servo_host_path localhost:9876 --method set --args "servo_v4_uart_cmd:'fakedisconnect 130 2400'"

  server    Starts the servod server for RPC calls. Mostly used for tests.
            Usage:
            cros-servod server [--log_path /tmp/servod/] [--server_port 80]

  --version Prints the version.

  --help    Prints the help.`
	defaultLogDirectory = "/tmp/servod/"
	defaultServerPort   = 80
	defaultServodPort   = 9999
)

// createLogFile creates a file and its parent directory for logging purpose.
func createLogFile(logPath string) (*os.File, error) {
	t := time.Now()
	fullPath := filepath.Join(logPath, t.Format("20060102-150405"))
	if err := os.MkdirAll(fullPath, 0755); err != nil {
		return nil, fmt.Errorf("failed to create directory %v: %v", fullPath, err)
	}

	logFullPathName := filepath.Join(fullPath, "log.txt")

	// Log the full output of the command to disk.
	logFile, err := os.Create(logFullPathName)
	if err != nil {
		return nil, fmt.Errorf("failed to create file %v: %v", fullPath, err)
	}
	return logFile, nil
}

// newLogger creates a logger. Using go default logger for now.
func newLogger(logFile *os.File) *log.Logger {
	mw := io.MultiWriter(logFile, os.Stderr)
	return log.New(mw, "", log.LstdFlags|log.LUTC)
}

func runCLI(ctx context.Context, cs model.CliSubcommand, d []string) int {
	a := model.CliArgs{}
	fs := flag.NewFlagSet("Run servod", flag.ExitOnError)
	fs.StringVar(&a.LogPath, "log_path", defaultLogDirectory, fmt.Sprintf("Path to record execution logs. The default value is %s", defaultLogDirectory))
	fs.StringVar(&a.ServoHostPath, "servo_host_path", "", "The path (URI) for the servod (containerized or running as a daemon) host.")
	fs.StringVar(&a.ServodDockerContainerName, "servod_docker_container_name", "", "The servod Docker container name.")
	fs.StringVar(&a.ServodDockerImagePath, "servod_docker_image_path", "", "The servod Docker image path to pull from GCR.")
	var servodPort int
	fs.IntVar(&servodPort, "servod_port", defaultServodPort, fmt.Sprintf("The --PORT parameter value for servod command. The default value is %d.", defaultServodPort))
	fs.StringVar(&a.Board, "board", "", "The --BOARD parameter value for servod command.")
	fs.StringVar(&a.Model, "model", "", "The --MODEL parameter value for servod command.")
	fs.StringVar(&a.SerialName, "serial_name", "", "The --SERIALNAME parameter value for servod command.")
	fs.StringVar(&a.Debug, "debug", "", "The --DEBUG parameter value for servod command.")
	fs.StringVar(&a.RecoveryMode, "recovery_mode", "", "The --RECOVERY_MODE parameter value for servod command.")
	fs.StringVar(&a.Config, "config", "", "The --CONFIG parameter value for servod command.")
	fs.StringVar(&a.AllowDualV4, "allow_dual_v4", "", "The --ALLOW-DUAL-V4 parameter value for servod command.")
	fs.StringVar(&a.Command, "command", "", "The command to execute inside the servod Docker container.")
	fs.StringVar(&a.Method, "method", "", "The method to call. Accepted values are doc, get, and set.")
	fs.StringVar(&a.Args, "args", "", "The arguments to pass to the method.")
	fs.Parse(d)
	a.ServodPort = int32(servodPort)

	logFile, err := createLogFile(a.LogPath)
	if err != nil {
		log.Fatalln("Failed to create log file", err)
		return 2
	}
	defer logFile.Close()

	logger := newLogger(logFile)
	commandexecutor := commandexecutor.NewServodCommandExecutor(logger)

	servodService, destructor, err := servodserver.NewServodService(ctx, logger, commandexecutor)
	defer destructor()
	if err != nil {
		logger.Fatalln("Failed to create servod service: ", err)
		return 2
	}

	if _, _, err := servodService.RunCli(cs, a, nil, true); err != nil {
		logger.Fatalln("Failed to run CLI: ", err)
		return 1
	}
	return 0
}

func startServer(ctx context.Context, d []string) int {
	a := model.CliArgs{}
	fs := flag.NewFlagSet("Start servod server", flag.ExitOnError)
	fs.StringVar(&a.LogPath, "log_path", defaultLogDirectory, fmt.Sprintf("The path to record execution logs. The default value is %s", defaultLogDirectory))
	var serverPort int
	fs.IntVar(&serverPort, "server_port", defaultServerPort, fmt.Sprintf("The port for the servod GRPC server. The default value is %d.", defaultServerPort))
	fs.Parse(d)
	a.ServerPort = int32(serverPort)

	logFile, err := createLogFile(a.LogPath)
	if err != nil {
		log.Fatalln("Failed to create log file", err)
		return 2
	}
	defer logFile.Close()

	logger := newLogger(logFile)
	commandexecutor := commandexecutor.NewServodCommandExecutor(logger)

	servodService, destructor, err := servodserver.NewServodService(ctx, logger, commandexecutor)
	defer destructor()
	if err != nil {
		logger.Fatalln("Failed to create servod service: ", err)
		return 2
	}

	if err := servodService.StartServer(a.ServerPort); err != nil {
		logger.Fatalln("Failed to start servod server: ", err)
		return 1
	}
	return 0
}

// Specify run mode for cros-servod.
type runMode string

const (
	runCli     runMode = "cli"
	runServer  runMode = "server"
	runVersion runMode = "version"
	runHelp    runMode = "help"
)

func getRunMode() (runMode, error) {
	if len(os.Args) > 1 {
		for _, a := range os.Args {
			if a == "--version" {
				return runVersion, nil
			}
		}
		switch strings.ToLower(os.Args[1]) {
		case "cli":
			return runCli, nil
		case "server":
			return runServer, nil
		}
	}
	// If we did not find special run mode then just print help for user.
	return runHelp, nil
}

func getCliSubcommand() (model.CliSubcommand, error) {
	if len(os.Args) > 2 {
		switch strings.ToLower(os.Args[2]) {
		case "start_servod":
			return model.CliStartServod, nil
		case "stop_servod":
			return model.CliStopServod, nil
		case "exec_cmd":
			return model.CliExecCmd, nil
		case "call_servod":
			return model.CliCallServod, nil
		}
	}
	return model.CliUnknown, errors.Reason("Unknown CLI subcommand").Err()
}

func mainInternal() int {
	rm, err := getRunMode()
	if err != nil {
		log.Fatalln(err)
		return 2
	}

	ctx := context.Background()
	switch rm {
	case runCli:
		log.Printf("Running CLI mode!")
		cs, err := getCliSubcommand()
		if err != nil {
			log.Fatalln(err)
			return 2
		}
		return runCLI(ctx, cs, os.Args[3:])
	case runServer:
		log.Printf("Running server mode!")
		return startServer(ctx, os.Args[2:])
	case runVersion:
		log.Printf("cros-servod version: %s", version)
		return 0
	}

	log.Println(helpDescription)
	return 0
}

func main() {
	os.Exit(mainInternal())
}
