// Copyright 2019 The ChromiumOS 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 main

import (
	"encoding/json"
	"fmt"
	"io/ioutil"
	"os"
	"path"
	"path/filepath"
	"strings"
)

type useTidyMode int

const clangTidyCrashSubstring = "PLEASE submit a bug report"

const (
	tidyModeNone useTidyMode = iota
	tidyModeAll
	tidyModeTricium
)

func processClangTidyFlags(builder *commandBuilder) (cSrcFile string, clangTidyFlags []string, mode useTidyMode) {
	builder.transformArgs(func(arg builderArg) string {
		const prefix = "-clang-tidy-flag="
		if !strings.HasPrefix(arg.value, prefix) {
			return arg.value
		}

		clangTidyFlags = append(clangTidyFlags, arg.value[len(prefix):])
		return ""
	})

	withTidy, _ := builder.env.getenv("WITH_TIDY")
	if withTidy == "" {
		return "", clangTidyFlags, tidyModeNone
	}
	srcFileSuffixes := []string{
		".c",
		".cc",
		".cpp",
		".C",
		".cxx",
		".c++",
	}
	cSrcFile = ""
	srcSuffix := ""
	lastArg := ""
	for _, arg := range builder.args {
		if lastArg != "-o" {
			for _, suffix := range srcFileSuffixes {
				if strings.HasSuffix(arg.value, suffix) {
					srcSuffix = suffix
					cSrcFile = arg.value
					break
				}
			}
		}
		lastArg = arg.value
	}

	if cSrcFile == "" {
		return "", clangTidyFlags, tidyModeNone
	}

	if withTidy == "tricium" {
		// Files generated from protobufs can result in _many_ clang-tidy complaints, and aren't
		// worth linting in general. Don't.
		if strings.HasSuffix(cSrcFile, ".pb"+srcSuffix) {
			mode = tidyModeNone
		} else {
			mode = tidyModeTricium
		}
	} else {
		mode = tidyModeAll
	}
	return cSrcFile, clangTidyFlags, mode
}

func calcClangTidyInvocation(env env, clangCmd *command, cSrcFile string, tidyFlags ...string) (*command, error) {
	resourceDir, err := getClangResourceDir(env, clangCmd.Path)
	if err != nil {
		return nil, err
	}

	clangTidyPath := filepath.Join(filepath.Dir(clangCmd.Path), "clang-tidy")
	args := append([]string{}, tidyFlags...)
	args = append(args, cSrcFile, "--", "-resource-dir="+resourceDir)
	args = append(args, clangCmd.Args...)
	return &command{
		Path:       clangTidyPath,
		Args:       args,
		EnvUpdates: clangCmd.EnvUpdates,
	}, nil
}

func runClangTidyForTricium(env env, clangCmd *command, cSrcFile, fixesDir string, extraTidyFlags []string, crashArtifactsDir string) error {
	if err := os.MkdirAll(fixesDir, 0777); err != nil {
		return fmt.Errorf("creating fixes directory at %q: %v", fixesDir, err)
	}

	f, err := ioutil.TempFile(fixesDir, "lints-")
	if err != nil {
		return fmt.Errorf("making tempfile for tidy: %v", err)
	}
	f.Close()

	// `f` is an 'anchor'; it ensures we won't create a similarly-named file in the future.
	// Hence, we can't delete it.
	fixesFilePath := f.Name() + ".yaml"
	fixesMetadataPath := f.Name() + ".json"

	// FIXME(gbiv): Remove `-checks=*` when testing is complete; we should defer to .clang-tidy
	// files, which are both more expressive and more approachable than `-checks=*`.
	extraTidyFlags = append(extraTidyFlags, "-checks=*", "--export-fixes="+fixesFilePath)
	clangTidyCmd, err := calcClangTidyInvocation(env, clangCmd, cSrcFile, extraTidyFlags...)
	if err != nil {
		return fmt.Errorf("calculating tidy invocation: %v", err)
	}

	stdstreams := &strings.Builder{}
	// Note: We pass nil as stdin as we checked before that the compiler
	// was invoked with a source file argument.
	exitCode, err := wrapSubprocessErrorWithSourceLoc(clangTidyCmd,
		env.run(clangTidyCmd, nil, stdstreams, stdstreams))
	if err != nil {
		return err
	}

	type crashOutput struct {
		CrashReproducerPath string `json:"crash_reproducer_path"`
		Stdstreams          string `json:"stdstreams"`
	}

	type metadata struct {
		Args        []string     `json:"args"`
		CrashOutput *crashOutput `json:"crash_output"`
		Executable  string       `json:"executable"`
		ExitCode    int          `json:"exit_code"`
		LintTarget  string       `json:"lint_target"`
		Stdstreams  string       `json:"stdstreams"`
		Wd          string       `json:"wd"`
	}

	meta := &metadata{
		Args:        clangTidyCmd.Args,
		CrashOutput: nil,
		Executable:  clangTidyCmd.Path,
		ExitCode:    exitCode,
		LintTarget:  cSrcFile,
		Stdstreams:  stdstreams.String(),
		Wd:          env.getwd(),
	}

	// Sometimes, clang-tidy crashes. Unfortunately, these don't get funnelled through the
	// standard clang crash machinery. :(. Try to work with our own.
	if crashArtifactsDir != "" && strings.Contains(meta.Stdstreams, clangTidyCrashSubstring) {
		tidyCrashArtifacts := path.Join(crashArtifactsDir, "clang-tidy")
		if err := os.MkdirAll(tidyCrashArtifacts, 0777); err != nil {
			return fmt.Errorf("creating crash artifacts directory at %q: %v", tidyCrashArtifacts, err)
		}

		f, err := ioutil.TempFile(tidyCrashArtifacts, "crash-")
		if err != nil {
			return fmt.Errorf("making tempfile for crash output: %v", err)
		}
		f.Close()

		reproCmd := &command{}
		*reproCmd = *clangCmd
		reproCmd.Args = append(reproCmd.Args, "-E", "-o", f.Name())

		reproOut := &strings.Builder{}
		_, err = wrapSubprocessErrorWithSourceLoc(reproCmd, env.run(reproCmd, nil, reproOut, reproOut))
		if err != nil {
			return fmt.Errorf("attempting to produce a clang-tidy crash reproducer: %v", err)
		}
		meta.CrashOutput = &crashOutput{
			CrashReproducerPath: f.Name(),
			Stdstreams:          reproOut.String(),
		}
	}

	f, err = os.Create(fixesMetadataPath)
	if err != nil {
		return fmt.Errorf("creating fixes metadata: %v", err)
	}

	if err := json.NewEncoder(f).Encode(meta); err != nil {
		return fmt.Errorf("writing fixes metadata: %v", err)
	}

	if err := f.Close(); err != nil {
		return fmt.Errorf("finalizing fixes metadata: %v", err)
	}
	return nil
}

func runClangTidy(env env, clangCmd *command, cSrcFile string, extraTidyFlags []string) error {
	extraTidyFlags = append(extraTidyFlags,
		"-checks="+strings.Join([]string{
			"*",
			"-bugprone-narrowing-conversions",
			"-cppcoreguidelines-*",
			"-fuchsia-*",
			"-google-readability*",
			"-google-runtime-references",
			"-hicpp-*",
			"-llvm-*",
			"-misc-non-private-member-variables-in-classes",
			"-misc-unused-parameters",
			"-modernize-*",
			"-readability-*",
		}, ","))
	clangTidyCmd, err := calcClangTidyInvocation(env, clangCmd, cSrcFile, extraTidyFlags...)
	if err != nil {
		return fmt.Errorf("calculating clang-tidy invocation: %v", err)
	}

	// Note: We pass nil as stdin as we checked before that the compiler
	// was invoked with a source file argument.
	exitCode, err := wrapSubprocessErrorWithSourceLoc(clangTidyCmd,
		env.run(clangTidyCmd, nil, env.stdout(), env.stderr()))
	if err == nil && exitCode != 0 {
		// Note: We continue on purpose when clang-tidy fails
		// to maintain compatibility with the previous wrapper.
		fmt.Fprint(env.stderr(), "clang-tidy failed")
	}
	return err
}

func hasAtLeastOneSuffix(s string, suffixes []string) bool {
	for _, suffix := range suffixes {
		if strings.HasSuffix(s, suffix) {
			return true
		}
	}
	return false
}
