// Package cloudlogger provides functionality to log text or json data to
// Google Cloud logging backend.
package cloudlogger

import (
	"context"
	"fmt"
	"os/exec"
	"strings"
	"time"

	"cloud.google.com/go/logging"
	"cos.googlesource.com/cos/tools.git/src/pkg/nodeprofiler/profiler"

	log "github.com/sirupsen/logrus"
)

const defaultCommandTimeout = 300 * time.Second

// componentInfo contains Name and Metrics fields similar to Name and Metrics
// fields that each profiler component has. componentInfo helps to export
// component fields to log them to Google Cloud Logging backend.
type componentInfo struct {
	Name       string
	Metrics    *profiler.USEMetrics
	Additional string
}

// ShellCmdOpts contains the options that each arbitrary shell command should
// be mapped to.
type ShellCmdOpts struct {
	// Specifies raw commands for which to log output.
	Command string `json:"Command"`
	// Specifies the number of times to run an arbitrary shell command.
	CmdCount int `json:"CmdCount"`
	// Specifies the interval separating the number of times the user runs
	// an arbitrary shell command.
	CmdInterval time.Duration `json:"CmdInterval"`
	// Specifies the amount of time it will take for the a raw shell command to
	// timeout.
	CmdTimeOut time.Duration `json: "CmdTimeOut"`
}

// LoggerOpts contains the options supported when logging the Profiler Report
// to Google Cloud Logging backend.
type LoggerOpts struct {
	// Specifies the project ID to write logs to.
	ProjID string `json:"ProjID"`
	// Specifies the commands to run mapped with their options.
	ShCmds []ShellCmdOpts `json:"ShCmds"`
	// Specifies the number of times to run the profiler.
	ProfilerCount int `json: "ProfilerCount"`
	// Specifies the interval the profiler will run.
	ProfilerInterval time.Duration `json: "ProfilerInterval"`
	// Components on which to run profiler. It may contain CPU(s), Memory, etc.
	Components []profiler.Component
	// ProfilerCmds field specifies additional options needed to run the profiler
	ProfilerCmds []profiler.Command
}

// TextLogger defines the method required to log a text string to Google Cloud
// logging backend.
type TextLogger interface {
	Printf(text string, a ...interface{})
}

// StructuredLogger defines the method required to log anything that can be
// marshaled to JSON to Google Cloud logging backend and the method that blocks
// buffered log entries until previous log entries are sent to Google Cloud
// logging backend.
type StructuredLogger interface {
	Log(l logging.Entry)
	Flush() error
}

// Validate ensures that options are correctly set. If they aren't, the method
// returns a list of error messages encountered. To log the output of a shell
// command, the user must specify both the command, command count and interval
// configurations which specify the command, how often to log its output and the
// interval in seconds. By default, the commands will timeout after 300 seconds
// unless the user specified a different value using the commandTimeout
// configuration. Similarly, to run the profiler, the user must specify a
// ProfilerCount configuration if a ProfilerInterval configuration was specified.
func (l *LoggerOpts) Validate() error {
	// A valid project ID must be provided.
	if l.ProjID == "" {
		return fmt.Errorf("invalid Logger options: cannot run profiler tool if the Cloud Logging Project ID is not set")
	}
	// To run the profiler, the profilerCount configuration has to be set if
	// profilerInterval configuration is set.
	if l.ProfilerCount == 0 && l.ProfilerInterval != 0 {
		return fmt.Errorf("invalid Logger options: cannot set ProfilerInterval if ProfilerCount is not set")
	}
	for _, shCmd := range l.ShCmds {
		// if the command configuration is nil, ensure CmdCount, CmdInterval, and
		// CmdTimeOut configurations are all 0.
		if shCmd.Command == "" {
			if shCmd.CmdCount != 0 || shCmd.CmdInterval != 0 || shCmd.CmdTimeOut != 0 {
				return fmt.Errorf("invalid Logger options: CmdCount, CmdInterval and CmdTimeout should not be set if Command is not set")
			}
		} else {
			// if the the command configuration was set, but the user did not specify
			// when the command will timeout, then the CmdTimeOut configuration will be
			// set to defaultCommandTimeout, which is 300 seconds.
			if shCmd.CmdTimeOut == 0 {
				shCmd.CmdTimeOut = defaultCommandTimeout
			}

			// if CmdCount config is not set, then CmdInterval must not be set.
			if shCmd.CmdCount == 0 && shCmd.CmdInterval != 0 {
				return fmt.Errorf("invalid Logger options: cannot set CmdInterval if CmdCount is not set")
			}
			// if the command configuration is set but no other options is set, run the
			// command once.
			if shCmd.CmdCount == 0 && shCmd.CmdInterval == 0 {
				shCmd.CmdCount = 1
			}
		}

	}

	return nil
}

// checkLogError returns nil if there was no error encountered while running the profiler/shell
// commands. If there was one or more error, a summary of errors encountered will be returned.
func checkLogError(emptyCmd bool, errArr []error) error {
	if len(errArr) == 0 {
		return nil
	}
	if emptyCmd == true {
		return fmt.Errorf("encountered %v errors while running the profiler: %v", len(errArr), errArr)
	}
	return fmt.Errorf("encountered %v errors while running the profiler and shell commands: %v", len(errArr), errArr)
}

// LogText writes the string infoToLog to a logging backend by calling the
// `Printf` method defined by the TextLogger interface.
// To log some text to Google Cloud Logging backend , pass in an instance of
// type *log.Logger.
func LogText(g TextLogger, infoToLog string) error {
	if infoToLog == "" {
		return fmt.Errorf("cannot log an empty string to Cloud Logging")
	}
	g.Printf(infoToLog)
	return nil
}

// logShellCmd writes a struct containing the name of an arbitrary shell
// command and its output to a logging backend by calling the `Log` method
// defined by the StructuredLogger interface. To Log a JSON Payload to Google
// Cloud Logging backend, pass in an instance of type *logging.Logger.
func logShellCommand(g StructuredLogger, cmdTimeOut time.Duration, cmd string, args ...string) error {
	// fullCommand string includes a main command and its options.
	// For `ps -aux` the cmd is `ps` the options are `-aux` thus the
	// fullCommand `ps -aux`
	var fullCommand string
	// formating commandName to not include blank spaces.
	if len(args) == 0 {
		fullCommand = cmd
	} else {
		fullCommand = cmd + " " + strings.Join(args, " ")
	}
	// Timeout after cmdTimeOut seconds.
	ctx, cancel := context.WithTimeout(context.Background(), cmdTimeOut)
	defer cancel()
	out, err := exec.CommandContext(ctx, cmd, args...).CombinedOutput()
	if ctx.Err() == context.DeadlineExceeded {
		err := "command timed out"
		log.Error(err)
		return fmt.Errorf("cannot log %v to Cloud Logging: %v", fullCommand, err)
	}

	if err != nil {
		return fmt.Errorf("cannot run %v command: %v", fullCommand, err)
	}
	entry := logging.Entry{
		Payload: struct {
			CommandName   string
			CommandOutput string
		}{
			CommandName:   fullCommand,
			CommandOutput: string(out),
		},
		Severity: logging.Debug,
	}
	g.Log(entry)
	return nil
}

// logUSEReport writes a USEReport to a logging backend by calling the `Log`
// method defined by the StructuredLogger interface. To log a JSON Payload to
// Google Cloud Logging backend, pass in an instance of type *logging.Logger.
func logUSEReport(g StructuredLogger, useReport *profiler.USEReport) error {
	if useReport == nil {
		return fmt.Errorf("cannot log an empty USEReport")
	}
	var cInfos []componentInfo
	for _, c := range useReport.Components {
		cInfos = append(cInfos, componentInfo{Name: c.Name(), Metrics: c.USEMetrics(), Additional: c.AdditionalInformation()})
	}
	entry := logging.Entry{
		// Log anything that can be marshaled to JSON.
		Payload: struct {
			Components []componentInfo
			Analysis   string
		}{
			Components: cInfos,
			Analysis:   useReport.Analysis,
		},
		Severity: logging.Debug,
	}
	g.Log(entry)
	return nil
}

// LogProfilerReport logs the output of logShellCommand and logUSEReport
// functions to a logger of type *logging.Logger. It takes as input the logger
// itself, and a pointer to a LoggerOpts struct that contains the shell command
// to execute, the number of time to execute that shell command, the interval
// between shell command executions, the time limit for shell command execution,
// the number of time to run the profiler tool, the interval between the number
// of times to run the profiler, and a profiler option struct that specify the
// component to generate USEReport for as well as any options associated to that
// component.
func LogProfilerReport(g StructuredLogger, opts *LoggerOpts) error {
	var emptyCmd bool
	errArr := []error{}
	log.Info("Validating logger options . . .")
	if err := opts.Validate(); err != nil {
		return err
	}
	log.Info("Done validating logger options.")
	// Ensure logging entries are written to the cloud logging backend.
	defer g.Flush()
	for _, shCmd := range opts.ShCmds {
		// Only log shell command if the user specified a command.
		if len(shCmd.Command) == 0 {
			emptyCmd = true
		} else {
			emptyCmd = false
			log.Infof("Running %v . . .", shCmd.Command)
			// Fetching command from user input and populating the cmdArray
			// with the main command and its flags.
			cmdArray := strings.Split(shCmd.Command, " ")
			usrMainCmd := cmdArray[0]
			usrMainCmdFlags := cmdArray[1:]
			for i := 0; i < shCmd.CmdCount; i++ {
				if err := logShellCommand(g, shCmd.CmdTimeOut, usrMainCmd, usrMainCmdFlags...); err != nil {
					errArr = append(errArr, err)
					continue
				}
				// Delaying execution by cmdInterval seconds.
				time.Sleep(shCmd.CmdInterval)

			}
			log.Infof("Done running %v\n", shCmd.Command)

		}
	}
	log.Info("Running Profiler . . .")
	// Run the profiler profCount times. The default value is 1 time unless user
	// set the counter to a different number.
	for i := 0; i < opts.ProfilerCount; i++ {
		useReport, err := profiler.GenerateUSEReport(opts.Components, opts.ProfilerCmds)
		if err != nil {
			errArr = append(errArr, fmt.Errorf("cannot run profiler.GenerateUSEReport(%v) = %v", opts.Components, err))
			continue
		}
		if err := logUSEReport(g, &useReport); err != nil {
			errArr = append(errArr, err)
			continue
		}
		// Delaying execution by profilerInterval seconds.
		time.Sleep(opts.ProfilerInterval)
	}
	log.Info("Done running profiler.")
	return checkLogError(emptyCmd, errArr)
}
