// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: MPL-2.0

package command

import (
	"encoding/json"
	"fmt"
	"os"
	"strings"

	"github.com/hashicorp/vault/command/healthcheck"

	"github.com/ghodss/yaml"
	"github.com/mitchellh/cli"
	"github.com/posener/complete"
	"github.com/ryanuber/columnize"
)

const (
	pkiRetOK int = iota
	pkiRetUsage
	pkiRetInformational
	pkiRetWarning
	pkiRetCritical
	pkiRetInvalidVersion
	pkiRetInsufficientPermissions
)

var (
	_ cli.Command             = (*PKIHealthCheckCommand)(nil)
	_ cli.CommandAutocomplete = (*PKIHealthCheckCommand)(nil)

	// Ensure the above return codes match (outside of OK/Usage) the values in
	// the healthcheck package.
	_ = pkiRetInformational == int(healthcheck.ResultInformational)
	_ = pkiRetWarning == int(healthcheck.ResultWarning)
	_ = pkiRetCritical == int(healthcheck.ResultCritical)
	_ = pkiRetInvalidVersion == int(healthcheck.ResultInvalidVersion)
	_ = pkiRetInsufficientPermissions == int(healthcheck.ResultInsufficientPermissions)
)

type PKIHealthCheckCommand struct {
	*BaseCommand

	flagConfig          string
	flagReturnIndicator string
	flagDefaultDisabled bool
	flagList            bool
}

func (c *PKIHealthCheckCommand) Synopsis() string {
	return "Check a PKI Secrets Engine mount's health and operational status"
}

func (c *PKIHealthCheckCommand) Help() string {
	helpText := `
Usage: vault pki health-check [options] MOUNT

  Reports status of the specified mount against best practices and pending
  failures. This is an informative command and not all recommendations will
  apply to all mounts; consider using a configuration file to tune the
  executed health checks.

  To check the pki-root mount with default configuration:

      $ vault pki health-check pki-root

  To specify a configuration:

      $ vault pki health-check -health-config=mycorp-root.json /pki-root

  Return codes indicate failure type:

      0 - Everything is good.
      1 - Usage error (check CLI parameters).
	  2 - Informational message from a health check.
	  3 - Warning message from a health check.
	  4 - Critical message from a health check.
	  5 - A version mismatch between health check and Vault Server occurred,
	      preventing one or more health checks from being run.
      6 - A permission denied message was returned from Vault Server for
	      one or more health checks.

For more detailed information, refer to the online documentation about the
vault pki health-check command.

` + c.Flags().Help()

	return strings.TrimSpace(helpText)
}

func (c *PKIHealthCheckCommand) Flags() *FlagSets {
	set := c.flagSet(FlagSetHTTP | FlagSetOutputFormat)
	f := set.NewFlagSet("Command Options")

	f.StringVar(&StringVar{
		Name:    "health-config",
		Target:  &c.flagConfig,
		Default: "",
		EnvVar:  "",
		Usage:   "Path to JSON configuration file to modify health check execution and parameters.",
	})

	f.StringVar(&StringVar{
		Name:       "return-indicator",
		Target:     &c.flagReturnIndicator,
		Default:    "default",
		EnvVar:     "",
		Completion: complete.PredictSet("default", "informational", "warning", "critical", "permission"),
		Usage: `Behavior of the return value:
 - permission, for exiting with a non-zero code when the tool lacks
               permissions or has a version mismatch with the server;
 - critical, for exiting with a non-zero code when a check returns a
             critical status in addition to the above;
 - warning, for exiting with a non-zero status when a check returns a
            warning status in addition to the above;
 - informational, for exiting with a non-zero status when a check returns
                  an informational status in addition to the above;
 - default, for the default behavior based on severity of message and
            only returning a zero exit status when all checks have passed
			and no execution errors have occurred.
		`,
	})

	f.BoolVar(&BoolVar{
		Name:    "default-disabled",
		Target:  &c.flagDefaultDisabled,
		Default: false,
		EnvVar:  "",
		Usage: `When specified, results in all health checks being disabled by
default unless enabled by the configuration file explicitly.`,
	})

	f.BoolVar(&BoolVar{
		Name:    "list",
		Target:  &c.flagList,
		Default: false,
		EnvVar:  "",
		Usage: `When specified, no health checks are run, but all known health
checks are printed.`,
	})

	return set
}

func (c *PKIHealthCheckCommand) isValidRetIndicator() bool {
	switch c.flagReturnIndicator {
	case "", "default", "informational", "warning", "critical", "permission":
		return true
	default:
		return false
	}
}

func (c *PKIHealthCheckCommand) AutocompleteArgs() complete.Predictor {
	// Return an anything predictor here, similar to `vault write`. We
	// don't know what values are valid for the mount path.
	return complete.PredictAnything
}

func (c *PKIHealthCheckCommand) AutocompleteFlags() complete.Flags {
	return c.Flags().Completions()
}

func (c *PKIHealthCheckCommand) Run(args []string) int {
	// Parse and validate the arguments.
	f := c.Flags()

	if err := f.Parse(args); err != nil {
		c.UI.Error(err.Error())
		return pkiRetUsage
	}

	args = f.Args()
	if !c.flagList && len(args) < 1 {
		c.UI.Error("Not enough arguments (expected mount path, got nothing)")
		return pkiRetUsage
	} else if !c.flagList && len(args) > 1 {
		c.UI.Error(fmt.Sprintf("Too many arguments (expected only mount path, got %d arguments)", len(args)))
		for _, arg := range args {
			if strings.HasPrefix(arg, "-") {
				c.UI.Warn(fmt.Sprintf("Options (%v) must be specified before positional arguments (%v)", arg, args[0]))
				break
			}
		}
		return pkiRetUsage
	}

	if !c.isValidRetIndicator() {
		c.UI.Error(fmt.Sprintf("Invalid flag -return-indicator=%v; known options are default, informational, warning, critical, and permission", c.flagReturnIndicator))
		return pkiRetUsage
	}

	// Setup the client and the executor.
	client, err := c.Client()
	if err != nil {
		c.UI.Error(err.Error())
		return pkiRetUsage
	}

	// When listing is enabled, we lack an argument here, but do not contact
	// the server at all, so we're safe to use a hard-coded default here.
	pkiPath := "<mount>"
	if len(args) == 1 {
		pkiPath = args[0]
	}

	mount := sanitizePath(pkiPath)
	executor := healthcheck.NewExecutor(client, mount)
	executor.AddCheck(healthcheck.NewCAValidityPeriodCheck())
	executor.AddCheck(healthcheck.NewCRLValidityPeriodCheck())
	executor.AddCheck(healthcheck.NewHardwareBackedRootCheck())
	executor.AddCheck(healthcheck.NewRootIssuedLeavesCheck())
	executor.AddCheck(healthcheck.NewRoleAllowsLocalhostCheck())
	executor.AddCheck(healthcheck.NewRoleAllowsGlobWildcardsCheck())
	executor.AddCheck(healthcheck.NewRoleNoStoreFalseCheck())
	executor.AddCheck(healthcheck.NewAuditVisibilityCheck())
	executor.AddCheck(healthcheck.NewAllowIfModifiedSinceCheck())
	executor.AddCheck(healthcheck.NewEnableAutoTidyCheck())
	executor.AddCheck(healthcheck.NewTidyLastRunCheck())
	executor.AddCheck(healthcheck.NewTooManyCertsCheck())
	executor.AddCheck(healthcheck.NewEnableAcmeIssuance())
	executor.AddCheck(healthcheck.NewAllowAcmeHeaders())
	if c.flagDefaultDisabled {
		executor.DefaultEnabled = false
	}

	// Handle listing, if necessary.
	if c.flagList {
		uiFormat := Format(c.UI)
		if uiFormat == "yaml" {
			c.UI.Error("YAML output format is not supported by the --list command")
			return pkiRetUsage
		}

		if uiFormat != "json" {
			c.UI.Output("Default health check config:")
		}
		config := map[string]map[string]interface{}{}
		for _, checker := range executor.Checkers {
			config[checker.Name()] = checker.DefaultConfig()
		}

		marshaled, err := json.MarshalIndent(config, "", "  ")
		if err != nil {
			c.UI.Error(fmt.Sprintf("Failed to marshal default config for check: %v", err))
			return pkiRetUsage
		}

		c.UI.Output(string(marshaled))
		return pkiRetOK
	}

	// Handle config merging.
	external_config := map[string]interface{}{}
	if c.flagConfig != "" {
		contents, err := os.Open(c.flagConfig)
		if err != nil {
			c.UI.Error(fmt.Sprintf("Failed to read configuration file %v: %v", c.flagConfig, err))
			return pkiRetUsage
		}

		decoder := json.NewDecoder(contents)
		decoder.UseNumber() // Use json.Number instead of float64 values as we are decoding to an interface{}.

		if err := decoder.Decode(&external_config); err != nil {
			c.UI.Error(fmt.Sprintf("Failed to parse configuration file %v: %v", c.flagConfig, err))
			return pkiRetUsage
		}
	}

	if err := executor.BuildConfig(external_config); err != nil {
		c.UI.Error(fmt.Sprintf("Failed to build health check configuration: %v", err))
		return pkiRetUsage
	}

	// Run the health checks.
	results, err := executor.Execute()
	if err != nil {
		c.UI.Error(fmt.Sprintf("Failed to run health check: %v", err))
		return pkiRetUsage
	}

	// Display the output.
	if err := c.outputResults(executor, results); err != nil {
		c.UI.Error(fmt.Sprintf("Failed to render results for display: %v", err))
	}

	// Select an appropriate return code.
	return c.selectRetCode(results)
}

func (c *PKIHealthCheckCommand) outputResults(e *healthcheck.Executor, results map[string][]*healthcheck.Result) error {
	switch Format(c.UI) {
	case "", "table":
		return c.outputResultsTable(e, results)
	case "json":
		return c.outputResultsJSON(results)
	case "yaml":
		return c.outputResultsYAML(results)
	default:
		return fmt.Errorf("unknown output format: %v", Format(c.UI))
	}
}

func (c *PKIHealthCheckCommand) outputResultsTable(e *healthcheck.Executor, results map[string][]*healthcheck.Result) error {
	// Iterate in checker order to ensure stable output.
	for _, checker := range e.Checkers {
		if !checker.IsEnabled() {
			continue
		}

		scanner := checker.Name()
		findings := results[scanner]

		c.UI.Output(scanner)
		c.UI.Output(strings.Repeat("-", len(scanner)))
		data := []string{"status" + hopeDelim + "endpoint" + hopeDelim + "message"}
		for _, finding := range findings {
			row := []string{
				finding.StatusDisplay,
				finding.Endpoint,
				finding.Message,
			}
			data = append(data, strings.Join(row, hopeDelim))
		}

		c.UI.Output(tableOutput(data, &columnize.Config{
			Delim: hopeDelim,
		}))
		c.UI.Output("\n")
	}

	return nil
}

func (c *PKIHealthCheckCommand) outputResultsJSON(results map[string][]*healthcheck.Result) error {
	bytes, err := json.MarshalIndent(results, "", "  ")
	if err != nil {
		return err
	}

	c.UI.Output(string(bytes))
	return nil
}

func (c *PKIHealthCheckCommand) outputResultsYAML(results map[string][]*healthcheck.Result) error {
	bytes, err := yaml.Marshal(results)
	if err != nil {
		return err
	}

	c.UI.Output(string(bytes))
	return nil
}

func (c *PKIHealthCheckCommand) selectRetCode(results map[string][]*healthcheck.Result) int {
	var highestResult healthcheck.ResultStatus = healthcheck.ResultNotApplicable
	for _, findings := range results {
		for _, finding := range findings {
			if finding.Status > highestResult {
				highestResult = finding.Status
			}
		}
	}

	cutOff := healthcheck.ResultInformational
	switch c.flagReturnIndicator {
	case "", "default", "informational":
	case "permission":
		cutOff = healthcheck.ResultInvalidVersion
	case "critical":
		cutOff = healthcheck.ResultCritical
	case "warning":
		cutOff = healthcheck.ResultWarning
	}

	if highestResult >= cutOff {
		return int(highestResult)
	}

	return pkiRetOK
}
