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

package tfjson

import (
	"encoding/json"
	"errors"
	"fmt"

	"github.com/hashicorp/go-version"
)

// ValidateFormatVersionConstraints defines the versions of the JSON
// validate format that are supported by this package.
var ValidateFormatVersionConstraints = ">= 0.1, < 2.0"

// Pos represents a position in a config file
type Pos struct {
	Line   int `json:"line"`
	Column int `json:"column"`
	Byte   int `json:"byte"`
}

// Range represents a range of bytes between two positions
type Range struct {
	Filename string `json:"filename"`
	Start    Pos    `json:"start"`
	End      Pos    `json:"end"`
}

type DiagnosticSeverity string

// These severities map to the tfdiags.Severity values, plus an explicit
// unknown in case that enum grows without us noticing here.
const (
	DiagnosticSeverityUnknown DiagnosticSeverity = "unknown"
	DiagnosticSeverityError   DiagnosticSeverity = "error"
	DiagnosticSeverityWarning DiagnosticSeverity = "warning"
)

// Diagnostic represents information to be presented to a user about an
// error or anomaly in parsing or evaluating configuration
type Diagnostic struct {
	Severity DiagnosticSeverity `json:"severity,omitempty"`

	Summary string `json:"summary,omitempty"`
	Detail  string `json:"detail,omitempty"`
	Range   *Range `json:"range,omitempty"`

	Snippet *DiagnosticSnippet `json:"snippet,omitempty"`
}

// DiagnosticSnippet represents source code information about the diagnostic.
// It is possible for a diagnostic to have a source (and therefore a range) but
// no source code can be found. In this case, the range field will be present and
// the snippet field will not.
type DiagnosticSnippet struct {
	// Context is derived from HCL's hcled.ContextString output. This gives a
	// high-level summary of the root context of the diagnostic: for example,
	// the resource block in which an expression causes an error.
	Context *string `json:"context"`

	// Code is a possibly-multi-line string of Terraform configuration, which
	// includes both the diagnostic source and any relevant context as defined
	// by the diagnostic.
	Code string `json:"code"`

	// StartLine is the line number in the source file for the first line of
	// the snippet code block. This is not necessarily the same as the value of
	// Range.Start.Line, as it is possible to have zero or more lines of
	// context source code before the diagnostic range starts.
	StartLine int `json:"start_line"`

	// HighlightStartOffset is the character offset into Code at which the
	// diagnostic source range starts, which ought to be highlighted as such by
	// the consumer of this data.
	HighlightStartOffset int `json:"highlight_start_offset"`

	// HighlightEndOffset is the character offset into Code at which the
	// diagnostic source range ends.
	HighlightEndOffset int `json:"highlight_end_offset"`

	// Values is a sorted slice of expression values which may be useful in
	// understanding the source of an error in a complex expression.
	Values []DiagnosticExpressionValue `json:"values"`
}

// DiagnosticExpressionValue represents an HCL traversal string (e.g.
// "var.foo") and a statement about its value while the expression was
// evaluated (e.g. "is a string", "will be known only after apply"). These are
// intended to help the consumer diagnose why an expression caused a diagnostic
// to be emitted.
type DiagnosticExpressionValue struct {
	Traversal string `json:"traversal"`
	Statement string `json:"statement"`
}

// ValidateOutput represents JSON output from terraform validate
// (available from 0.12 onwards)
type ValidateOutput struct {
	FormatVersion string `json:"format_version"`

	Valid        bool         `json:"valid"`
	ErrorCount   int          `json:"error_count"`
	WarningCount int          `json:"warning_count"`
	Diagnostics  []Diagnostic `json:"diagnostics"`
}

// Validate checks to ensure that data is present, and the
// version matches the version supported by this library.
func (vo *ValidateOutput) Validate() error {
	if vo == nil {
		return errors.New("validation output is nil")
	}

	if vo.FormatVersion == "" {
		// The format was not versioned in the past
		return nil
	}

	constraint, err := version.NewConstraint(ValidateFormatVersionConstraints)
	if err != nil {
		return fmt.Errorf("invalid version constraint: %w", err)
	}

	version, err := version.NewVersion(vo.FormatVersion)
	if err != nil {
		return fmt.Errorf("invalid format version %q: %w", vo.FormatVersion, err)
	}

	if !constraint.Check(version) {
		return fmt.Errorf("unsupported validation output format version: %q does not satisfy %q",
			version, constraint)
	}

	return nil
}

func (vo *ValidateOutput) UnmarshalJSON(b []byte) error {
	type rawOutput ValidateOutput
	var schemas rawOutput

	err := json.Unmarshal(b, &schemas)
	if err != nil {
		return err
	}

	*vo = *(*ValidateOutput)(&schemas)

	return vo.Validate()
}
