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

package staticanalysis

import (
	"context"
	"fmt"
	"path"
	"path/filepath"
	"strings"
)

// Analyzer is the interface that must be implemented for each linter/formatter
// that integrates with this tool.
type Analyzer interface {
	// Analyze validates a single source file, returning any findings.
	//
	// The `path` argument is relative to the checkout root.
	Analyze(ctx context.Context, path string) ([]*Finding, error)
}

// A suggested replacement.
//
// The replacement should be for one continuous section of a file.
type Replacement struct {
	// Path to the file for this replacement.
	//
	// An empty string indicates the commit message.
	Path string `json:"path"`

	// A replacement string.
	Replacement string `json:"replacement"`

	// A continuous section of the file to replace. Required.
	StartLine int `json:"start_line"` // 1-based, inclusive.
	EndLine   int `json:"end_line"`   // 1-based, inclusive.
	StartChar int `json:"start_char"` // 0-based, inclusive.
	EndChar   int `json:"end_char"`   // 0-based, exclusive.
}

// A suggestion is associated with a single finding and contains a list of
// possible replacement texts for the text that the finding covers.
type Suggestion struct {
	Description string `json:"description"`

	Replacements []Replacement `json:"replacements"`
}

// Finding is the common schema that all linters' and formatters' outputs must
// be converted to in order to be compatible with this tool. Each Finding that
// applies to lines that are affected by the change under test may be posted as
// a Gerrit comment.
//
// Mirrors the Tricium comment schema:
// https://chromium.googlesource.com/infra/infra/+/3b0abf2fb146af025440a48e1f7423595b1a5bfb/go/src/infra/tricium/api/v1/data.proto#122
//
// TODO(olivernewman): Make this a proper proto file that gets copied into the
// recipes repository.
type Finding struct {
	// Category is the text that will be used as the header of the Gerrit
	// comment emitted for this finding.
	//
	// Should be of the form "<tool name>/<error level>/<error type>" for
	// linters, e.g. "Clippy/warning/bool_comparison", or just the name of the
	// tool for things like auto-formatters, e.g. "Gofmt".
	//
	// Required.
	Category string `json:"category"`

	// Message is a human-readable description of the finding, e.g. "variable
	// foo is not defined".
	//
	// Required.
	Message string `json:"message"`

	// Path is the path to the file within a fuchsia checkout, using forward
	// slashes as delimiters, e.g. "src/foo/bar.cc"
	//
	// If omitted, the finding will apply to the change's commit message.
	Path string `json:"path"`

	// StartLine is the starting line of the chunk of the file that the finding
	// applies to (1-indexed, inclusive).
	//
	// If omitted, the finding will apply to the entire file and a top-level
	// file comment will be emitted.
	StartLine int `json:"start_line,omitempty"`

	// EndLine is the ending line of the chunk of the file that the finding
	// applies to (1-indexed, inclusive).
	//
	// If set, must be greater than or equal to StartLine.
	//
	// If omitted, Endline is assumed to be equal to StartLine.
	EndLine int `json:"end_line,omitempty"`

	// StartChar is the index of the first character within StartLine that the
	// finding applies to (0-indexed, inclusive).
	//
	// If omitted, the finding will apply to the entire line.
	StartChar int `json:"start_char,omitempty"`

	// EndChar is the index of the last character within EndLine that the
	// finding applies to (0-indexed, exclusive).
	//
	// Required if StartChar is specified. If StartLine==EndLine, EndChar must
	// be greater than StartChar.
	EndChar int `json:"end_char,omitempty"`

	// Suggestions is a list of possible strings that could replace the text
	// highlighted by the finding.
	//
	// If set, all of StartLine, EndLine, StartChar, and EndChar must be
	// specified.
	Suggestions []Suggestion `json:"suggestions,omitempty"`
}

// Normalize makes a best effort at updating invalid/inconsistent fields to be
// sensible, returning an error if there are any field values that are invalid
// and for which a valid value cannot be determined.
//
// In an ideal world we would *validate* each analyzer finding rather than
// emitting different values from what the analyzers produce. But that would
// require potentially tedious and repetitive normalization logic in each
// analyzer, so instead we centralize the normalization logic here to make it
// easier to write new analyzers.
func (f *Finding) Normalize() error {
	if f.Category == "" {
		return fmt.Errorf("category must be set for finding: %#+v", f)
	}

	if f.Message == "" {
		return fmt.Errorf("message must be set for finding: %#+v", f)
	}

	// It's okay for Path to not be set, in which case the finding will be
	// interpreted as applying to the entire change.
	if f.Path != "" {
		if path.IsAbs(f.Path) || strings.HasPrefix(f.Path, "..") || f.Path != path.Clean(f.Path) {
			return fmt.Errorf("path must be a clean source-relative path for finding: %#+v", f)
		}
	}

	if f.StartLine > 0 {
		if f.EndLine == 0 {
			// If unset, update EndLine to be equal to StartLine.
			f.EndLine = f.StartLine
		}
		if f.StartLine == f.EndLine && f.StartChar > 0 && f.StartChar == f.EndChar {
			// Fix the common case where an analyzer emits StartChar and EndChar
			// of the same value to highlight a single-character.
			f.EndChar = f.StartChar + 1
		}

		if f.StartLine > f.EndLine || (f.StartLine == f.EndLine && f.StartChar > 0 && f.StartChar >= f.EndChar) {
			return fmt.Errorf("(start_line, start_char) must be before (end_line, end_char) for finding: %#+v", f)
		}
	} else if f.EndLine > 0 || f.StartChar > 0 || f.EndChar > 0 {
		return fmt.Errorf("start_line is unexpectedly unset for finding: %#+v", f)
	}

	if len(f.Suggestions) > 0 && (f.StartLine < 1 || f.EndLine < 1 || f.StartChar < 0 || f.EndChar <= 0) {
		return fmt.Errorf("a finding with suggestions must have a fully specified span: %#+v", f)
	}

	for _, suggestion := range f.Suggestions {
		for _, r := range suggestion.Replacements {
			if r.StartLine < 1 || r.EndLine < 1 || r.StartChar < 0 || r.EndChar < 0 {
				return fmt.Errorf("a suggested replacement must have a fully specified span: %#+v", r)
			}
			// StartChar==EndChar is allowed for a replacement span because a
			// replacement might just insert text without replacing any
			// pre-existing text.
			if r.StartLine > r.EndLine || (r.StartLine == r.EndLine && r.StartChar > r.EndChar) {
				return fmt.Errorf("(start_line, start_char) must be before (end_line, end_char) for replacement in finding: %#+v", f)
			}
		}
	}

	return nil
}

// BuildPathToCheckoutPath converts a path relative to the build directory into
// a source-relative path with platform-agnostic separators.
//
// E.g. "../../src/foo/bar.py" -> "src/foo/bar.py".
func BuildPathToCheckoutPath(path, buildDir, checkoutDir string) (string, error) {
	absPath := filepath.Clean(filepath.Join(buildDir, path))
	path, err := filepath.Rel(checkoutDir, absPath)
	if err != nil {
		return "", err
	}
	return filepath.ToSlash(path), nil
}
