/*
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/",
			"user/src/",
			"user/super/com/google/gwt/emul/",
			"user/super/com/google/gwt/junit/translatable/",
			"codeserver/java/",
			"samples/",
		},
		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-super/com/google/",
			"user/test/test/",
			"dev/core/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,}")
var footerRegexp = regexp.MustCompile("^[A-Za-z0-9-]+:")

func (l *linter) checkMessage(commitmsg []string, offset int) {
	warn := func(line int, message string) {
		l.comment("/COMMIT_MSG", line+offset, "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
		}
	}

	// Note: don't check subject line
	for i, inFooter := len(commitmsg)-1, true; i >= 1; i-- {
		if len(commitmsg[i]) == 0 {
			inFooter = false
			continue
		}
		if !footerRegexp.MatchString(commitmsg[i]) {
			if inFooter {
				warn(i+1, "Footer lines should be separated from message body by a blank line.")
			}
			break
		}
		if !inFooter {
			warn(i+1, "Footer lines should form a single paragraph (i.e. must not be separated by blank lines.)")
		}
		field := strings.SplitN(commitmsg[i], ":", 2)[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
	}
	// Gerrit always adds 1 line per parent and 4 lines for authorship as header,
	// and 1 blank line as separator; let's compute the offset.
	// See https://gerrit.googlesource.com/gerrit/+/master/gerrit-server/src/main/java/com/google/gerrit/server/patch/Text.java
	parents, err := git.Line("show", "-s", "--pretty=tformat:%P", rev)
	if err != nil {
		return err
	}
	parentCount := len(strings.Split(parents, " "))
	linter.checkMessage(commitmsg, parentCount+5)

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

	if linter.failed {
		return LintFailed
	}
	return nil
}
