/*
Copyright 2013 Google Inc. All Rights Reserved.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

// Package lint provides helper methods for quickly running lint checks
// against a proposed change on Gerrit.
package lint

import (
	"errors"
	"fmt"
	"log"
	"regexp"
	"strings"

	"gwt.googlesource.com/buildglue.git/checkstyle"
	"gwt.googlesource.com/buildglue.git/gerrit"
	"gwt.googlesource.com/buildglue.git/git"
)

// Errors that can be returned by Lint.
var (
	LintFailed = errors.New("commit failed lint checking")
)

// Should be kept in sync with GWT's build.xml files.
var checks = []struct {
	config   string
	includes []string
	excludes []string
}{
	{
		config: "eclipse/settings/code-style/gwt-checkstyle.xml",
		includes: []string{
			"dev/core/src/",
			"dev/core/super/com/google/gwt/dev/jjs/intrinsic/",
			"user/src/",
			"user/super/com/google/gwt/emul/",
			"user/super/com/google/gwt/junit/translatable/",
		},
		excludes: []string{
			"dev/core/src/com/google/gwt/dev/shell/remoteui/RemoteMessageProto.java",
			"dev/core/src/com/google/gwt/dev/asm/",
			"dev/core/src/com/google/gwt/dev/js/rhino/",
			"dev/core/src/org/eclipse/",
			"dev/core/src/org/apache/",
			"user/src/javax/validation/",
			"user/src/org/hibernate/validator/",
		},
	},
	{
		config: "eclipse/settings/code-style/gwt-checkstyle-tests.xml",
		includes: []string{
			"user/test/com/google/",
			"user/test/test/",
		},
	},
}

// Match returns true if file is a ".java" file that starts with a string
// from includes but does not start with any strings from excludes.
func match(file string, includes, excludes []string) bool {
	if !strings.HasSuffix(file, ".java") {
		return false
	}
	for _, exclude := range excludes {
		if strings.HasPrefix(file, exclude) {
			return false
		}
	}
	for _, include := range includes {
		if strings.HasPrefix(file, include) {
			return true
		}
	}
	return false
}

// Matches returns the sublist of files that match the provided includes
// and excludes rules.
func matches(files, includes, excludes []string) []string {
	res := []string{}
	for _, file := range files {
		if match(file, includes, excludes) {
			res = append(res, file)
		}
	}
	return res
}

type linter struct {
	rev      string
	comments map[string][]gerrit.Comment
	failed   bool
}

func newLinter(rev string) *linter {
	return &linter{
		rev:      rev,
		comments: make(map[string][]gerrit.Comment),
	}
}

func (l *linter) comment(file string, line int, severity, message string) {
	comment := gerrit.Comment{Line: line, Message: fmt.Sprintf("[%s] %s", severity, message)}
	l.comments[file] = append(l.comments[file], comment)
	if severity == "error" {
		l.failed = true
	}
}

func (l *linter) checkStyle(config string, files []string) error {
	out, err := checkstyle.Run(config, files)
	if err != nil {
		log.Println("running checkstyle failed:", err)
		return err
	}
	for _, file := range out {
		if len(file.Errors) == 0 {
			continue
		}
		blameable, err := git.Blame(l.rev, file.Name)
		if err != nil {
			return err
		}
		for _, err := range file.Errors {
			if blameable[err.Line] {
				l.comment(file.Name, err.Line, err.Severity, err.Message)
			}
		}
	}
	return nil
}

var fixesIssueRegexp = regexp.MustCompile("(?i)^fixes issue [0-9]{3,}[.]?$")
var issueRegexp = regexp.MustCompile("(?i)issue [0-9]{3,}")

func (l *linter) checkMessage(commitmsg []string) {
	warn := func(line int, message string) {
		// Gerrit includes some extra header lines before the commit message.
		// TODO(mdempsky): Is it always exactly six lines?
		l.comment("/COMMIT_MSG", line+6, "warning", message)
	}

	lengthWarning := false
	bugWarning := false

	if len(commitmsg) >= 3 && len(commitmsg[1]) > 0 {
		warn(2, "Subject line and body should be separated by a blank line.")
	}
	for i, line := range commitmsg {
		if !lengthWarning && i != 1 && len(line) > 72 {
			warn(i+1, "Commit message lines should be 72 characters or fewer.")
			lengthWarning = true
		}
		if !bugWarning && ((i == 0 && issueRegexp.MatchString(line)) || fixesIssueRegexp.MatchString(line)) {
			warn(i+1, "Please use 'Bug: issue NNNN' and place it just above the Change-Id line.")
			bugWarning = true
		}
	}

	for i := len(commitmsg) - 1; i >= 0 && len(commitmsg[i]) > 0; i-- {
		if commitmsg[i][0] == ' ' {
			continue
		}
		field := strings.TrimSpace(strings.Split(commitmsg[i], ":")[0])
		if field != strings.Title(field) {
			warn(i+1, "Footer fields should be in Title-Case.")
			break
		}
	}
}

func (l *linter) review() gerrit.Review {
	res := gerrit.Review{}
	if l.failed {
		res.Message = ("Oops, this change failed the fast style check! " +
			"Please fix all errors and try again.")
		res.Labels = &gerrit.Labels{Verified: -1}
	} else if len(l.comments) != 0 {
		res.Message = ("This change passed the fast style check, " +
			"but still triggered some non-error warnings. " +
			"Please review and fix if appropriate.")
	} else {
		res.Message = ("Woo hoo, this change passed the fast style check " +
			"with ZERO new warnings! You rock!")
	}
	if len(l.comments) != 0 {
		res.Comments = l.comments
	}
	return res
}

// Lint fetches ref from Gerrit, inspects the commit message and runs checkstyle against
// any added or modified files, and posts a review to Gerrit with the results.
// Returns a LintFailed error if any lint errors were found.
func Lint(ref string) error {
	if err := git.Run("fetch", "https://gwt.googlesource.com/gwt", ref); err != nil {
		log.Println("fetch failed:", err)
		return err
	}
	rev, err := git.Line("rev-parse", "FETCH_HEAD")
	if err != nil {
		return err
	}
	if err = git.Run("checkout", rev); err != nil {
		return err
	}
	files, err := git.Lines("diff-tree", "-r", "--name-only", "--diff-filter=AM", rev+"^", rev)
	if err != nil {
		return err
	}

	log.Println("running lint checks")

	linter := newLinter(rev)
	for _, check := range checks {
		if err := linter.checkStyle(check.config, matches(files, check.includes, check.excludes)); err != nil {
			log.Println("checkstyle error:", err)
			return err
		}
	}

	commitmsg, err := git.Lines("show", "-s", "--pretty=format:%B", rev)
	if err != nil {
		return err
	}
	linter.checkMessage(commitmsg)

	if err = gerrit.Post(ref, linter.review()); err != nil {
		return err
	}

	if linter.failed {
		return LintFailed
	}
	return nil
}
