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

// The following enables go generate to generate the doc.go file.
//go:generate go run $JIRI_ROOT/release/go/src/v.io/x/lib/cmdline/testdata/gendoc.go -env=CMDLINE_PREFIX=jiri .

package main

import (
	"bufio"
	"bytes"
	"fmt"
	"io"
	"os"
	"path/filepath"
	"regexp"
	"strings"

	"v.io/jiri"
	"v.io/jiri/collect"
	"v.io/jiri/gitutil"
	"v.io/jiri/profiles"
	"v.io/jiri/profiles/profilescmdline"
	"v.io/jiri/profiles/profilesreader"
	"v.io/jiri/project"
	"v.io/jiri/runutil"
	"v.io/jiri/tool"
	"v.io/x/devtools/tooldata"
	"v.io/x/lib/cmdline"
	"v.io/x/lib/envvar"
)

var (
	detailedOutputFlag bool
	gotoolsBinPathFlag string
	readerFlags        profilescmdline.ReaderFlagValues

	commentRE = regexp.MustCompile("^($|[:space:]*#)")
)

func init() {
	cmdAPICheck.Flags.BoolVar(&detailedOutputFlag, "detailed", true, "If true, shows each API change in an expanded form. Otherwise, only a summary is shown.")
	cmdAPI.Flags.StringVar(&gotoolsBinPathFlag, "gotools-bin", "", "The path to the gotools binary to use. If empty, gotools will be built if necessary.")
	profilescmdline.RegisterReaderFlags(&cmdAPI.Flags, &readerFlags, "v23:base", jiri.ProfilesDBDir)
	tool.InitializeProjectFlags(&cmdAPI.Flags)
	tool.InitializeRunFlags(&cmdAPI.Flags)
}

// cmdAPI represents the "jiri api" command.
var cmdAPI = &cmdline.Command{
	Name:     "api",
	Short:    "Manage vanadium public API",
	Long:     "Use this command to ensure that no unintended changes are made to the vanadium public API.",
	Children: []*cmdline.Command{cmdAPICheck, cmdAPIUpdate},
}

// cmdAPICheck represents the "jiri api check" command.
var cmdAPICheck = &cmdline.Command{
	Runner:   jiri.RunnerFunc(runAPICheck),
	Name:     "check",
	Short:    "Check if any changes have been made to the public API",
	Long:     "Check if any changes have been made to the public API.",
	ArgsName: "<projects>",
	ArgsLong: "<projects> is a list of vanadium projects to check. If none are specified, all projects that require a public API check upon presubmit are checked.",
}

func readAPIFileContents(jirix *jiri.X, path string) (_ []byte, e error) {
	s := jirix.NewSeq()
	var buf bytes.Buffer
	file, err := s.Open(path)
	defer collect.Error(file.Close, &e)
	if err != nil {
		return nil, err
	}
	reader := bufio.NewReader(file)
	for {
		line, err := reader.ReadBytes('\n')
		if !commentRE.Match(line) {
			buf.Write(line)
		}
		if err == io.EOF {
			break
		} else if err != nil {
			return nil, err
		}
	}
	return buf.Bytes(), err
}

type packageChange struct {
	name          string
	projectName   string
	apiFilePath   string
	oldAPI        map[string]bool // set
	newAPI        map[string]bool // set
	newAPIContent []byte

	// If true, indicates that there was a problem reading the old API file.
	apiFileError error
}

// buildGotools builds the gotools binary and returns the path to the built
// binary and the function to call to clean up the built binary (always
// non-nil). If the binary could not be built, the empty string and a non-nil
// error are returned.
//
// If the gotools_bin flag is specified, that path, a no-op cleanup and a
// nil error are returned.
func buildGotools(jirix *jiri.X) (string, func() error, error) {
	nopCleanup := func() error { return nil }
	if gotoolsBinPathFlag != "" {
		return gotoolsBinPathFlag, nopCleanup, nil
	}

	// Determine the location of the gotools source.
	projects, err := project.LocalProjects(jirix, project.FastScan)
	if err != nil {
		return "", nopCleanup, err
	}
	project, err := projects.FindUnique("third_party")
	if err != nil {
		return "", nopCleanup, fmt.Errorf("error finding project %q: %v", "third_party", err)
	}
	newGoPath := filepath.Join(project.Path, "go")

	s := jirix.NewSeq()

	// Build the gotools binary.
	tempDir, err := s.TempDir("", "")
	if err != nil {
		return "", nopCleanup, err
	}
	cleanup := func() error { return jirix.NewSeq().RemoveAll(tempDir).Done() }

	gotoolsBin := filepath.Join(tempDir, "gotools")
	env := envvar.CopyMap(jirix.Env())
	env["GOPATH"] = newGoPath
	if err := s.Env(env).Last("go", "build", "-o", gotoolsBin, "github.com/visualfc/gotools"); err != nil {
		return "", cleanup, err
	}

	return gotoolsBin, cleanup, nil
}

// getCurrentAPI runs the gotools api command against the given directory and
// returns the bytes that should go into the .api file for that directory.
func getCurrentAPI(jirix *jiri.X, gotoolsBin, dir string) ([]byte, error) {
	rd, err := profilesreader.NewReader(jirix, readerFlags.ProfilesMode, readerFlags.DBFilename)
	if err != nil {
		return nil, err
	}
	rd.MergeEnvFromProfiles(readerFlags.MergePolicies, profiles.NativeTarget(), "jiri")
	s := jirix.NewSeq()
	var output bytes.Buffer
	if err := s.Capture(&output, nil).Env(rd.ToMap()).Last(gotoolsBin, "goapi", dir); err != nil {
		return nil, err
	}
	return output.Bytes(), nil
}

func isFailedAPICheckFatal(projectName string, apiCheckProjects map[string]struct{}, apiFileError error) bool {
	if runutil.IsNotExist(apiFileError) {
		if _, ok := apiCheckProjects[projectName]; !ok {
			return false
		}
	}
	return true
}

func shouldIgnoreFile(file string) bool {
	if !strings.HasSuffix(file, ".go") {
		return true
	}
	pathComponents := strings.Split(file, string(os.PathSeparator))
	for _, component := range pathComponents {
		if component == "testdata" || component == "internal" {
			return true
		}
	}
	return false
}

func splitLinesToSet(in []byte) map[string]bool {
	result := make(map[string]bool)
	scanner := bufio.NewScanner(bytes.NewReader(in))
	for scanner.Scan() {
		result[scanner.Text()] = true
	}
	return result
}

func packageName(path string) string {
	components := strings.Split(path, string(os.PathSeparator))
	for i, component := range components {
		if component == "src" {
			return strings.Join(components[i+1:], "/")
		}
	}
	return ""
}

func getPackageChanges(jirix *jiri.X, apiCheckProjects map[string]struct{}, args []string) (changes []packageChange, e error) {
	gotoolsBin, cleanup, err := buildGotools(jirix)
	if err != nil {
		return nil, err
	}
	defer collect.Error(cleanup, &e)
	projects, err := project.ParseNames(jirix, args, apiCheckProjects)
	if err != nil {
		return nil, err
	}
	for _, project := range projects {
		path := project.Path
		branch, err := gitutil.New(jirix.NewSeq(), gitutil.RootDirOpt(path)).CurrentBranchName()
		if err != nil {
			return nil, err
		}
		files, err := gitutil.New(jirix.NewSeq(), gitutil.RootDirOpt(path)).ModifiedFiles("master", branch)
		if err != nil {
			return nil, err
		}
		// Extract the directories for these files.
		dirs := make(map[string]bool) // set
		for _, file := range files {
			if !shouldIgnoreFile(file) {
				dirs[filepath.Join(path, filepath.Dir(file))] = true
			}
		}
		if len(dirs) == 0 {
			continue
		}
		for dir := range dirs {
			// Read the API state in the working directory.
			currentAPI, err := getCurrentAPI(jirix, gotoolsBin, dir)
			if err != nil {
				return nil, err
			}
			// Read the existing public API file.
			apiFilePath := filepath.Join(dir, ".api")
			apiFileContents, apiFileError := readAPIFileContents(jirix, apiFilePath)
			if apiFileError != nil {
				if runutil.IsNotExist(apiFileError) && len(currentAPI) == 0 {
					// The API file doesn't exist but the
					// public API in the working directory
					// is empty anyway.
					continue
				}
				if !isFailedAPICheckFatal(project.Name, apiCheckProjects, apiFileError) {
					// We couldn't read the API file, but this project doesn't
					// require one.  Just warn the user.
					fmt.Fprintf(jirix.Stderr(), "WARNING: could not read public API from %s: %v\n", apiFilePath, err)
					fmt.Fprintf(jirix.Stderr(), "WARNING: skipping public API check for %s\n", dir)
					continue
				}
			}
			if apiFileError != nil || !bytes.Equal(currentAPI, apiFileContents) {
				pkgName := packageName(dir)
				if pkgName == "" {
					pkgName = dir
				}
				// The user has changed the public API or we
				// couldn't read the public API in the first
				// place.
				changes = append(changes, packageChange{
					name:          pkgName,
					projectName:   project.Name,
					apiFilePath:   apiFilePath,
					oldAPI:        splitLinesToSet(apiFileContents),
					newAPI:        splitLinesToSet(currentAPI),
					newAPIContent: currentAPI,
					apiFileError:  apiFileError,
				})
			}
		}
	}
	return
}

func runAPICheck(jirix *jiri.X, args []string) error {
	return doAPICheck(jirix, args, detailedOutputFlag)
}

func printChangeSummary(out io.Writer, change packageChange, detailedOutput bool) {
	var removedEntries []string
	var addedEntries []string
	for entry, _ := range change.oldAPI {
		if !change.newAPI[entry] {
			removedEntries = append(removedEntries, entry)
		}
	}
	for entry, _ := range change.newAPI {
		if !change.oldAPI[entry] {
			addedEntries = append(addedEntries, entry)
		}
	}
	if detailedOutput {
		fmt.Fprintf(out, "Changes for package %s\n", change.name)
		if len(removedEntries) > 0 {
			fmt.Fprintf(out, "The following %d entries were removed:\n", len(removedEntries))
			for _, entry := range removedEntries {
				fmt.Fprintf(out, "\t%s\n", entry)
			}
		}
		if len(addedEntries) > 0 {
			fmt.Fprintf(out, "The following %d entries were added:\n", len(addedEntries))
			for _, entry := range addedEntries {
				fmt.Fprintf(out, "\t%s\n", entry)
			}
		}
	} else {
		fmt.Fprintf(out, "package %s: %d entries removed, %d entries added\n", change.name, len(removedEntries), len(addedEntries))
	}
}

func doAPICheck(jirix *jiri.X, args []string, detailedOutput bool) error {
	config, err := tooldata.LoadConfig(jirix)
	if err != nil {
		return err
	}
	changes, err := getPackageChanges(jirix, config.APICheckProjects(), args)
	if err != nil {
		return err
	} else if len(changes) > 0 {
		for _, change := range changes {
			if change.apiFileError != nil {
				fmt.Fprintf(jirix.Stdout(), "ERROR: package %s: could not read the package's .api file: %v\n", change.name, change.apiFileError)
				fmt.Fprintf(jirix.Stdout(), "ERROR: a readable .api file is required for all packages in project %s\n", change.projectName)
			} else {
				printChangeSummary(jirix.Stdout(), change, detailedOutput)
			}
		}
	}
	return nil
}

// cmdAPIUpdate represents the "jiri api fix" command.
var cmdAPIUpdate = &cmdline.Command{
	Runner:   jiri.RunnerFunc(runAPIFix),
	Name:     "fix",
	Short:    "Update api files to reflect changes to the public API",
	Long:     "Update .api files to reflect changes to the public API.",
	ArgsName: "<projects>",
	ArgsLong: "<projects> is a list of vanadium projects to update. If none are specified, all project APIs are updated.",
}

func runAPIFix(jirix *jiri.X, args []string) error {
	config, err := tooldata.LoadConfig(jirix)
	if err != nil {
		return err
	}
	changes, err := getPackageChanges(jirix, config.APICheckProjects(), args)
	if err != nil {
		return err
	}
	s := jirix.NewSeq()
	for _, change := range changes {
		if len(change.newAPIContent) == 0 {
			if _, err := s.Stat(change.apiFilePath); !runutil.IsNotExist(err) {
				if err != nil {
					return err
				}
				// No API contents? Remove the file.
				if err := s.RemoveAll(change.apiFilePath).Done(); err != nil {
					return err
				}
			}
		} else if err := s.WriteFile(change.apiFilePath, []byte(change.newAPIContent), 0644).Done(); err != nil {
			return fmt.Errorf("WriteFile(%s) failed: %v", change.apiFilePath, err)
		}
		fmt.Fprintf(jirix.Stdout(), "Updated %s.\n", change.apiFilePath)
	}
	return nil
}

func main() {
	cmdline.Main(cmdAPI)
}
