/*
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"
	"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
}

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)
	}

	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 i != 1 && len(line) > 72 {
			warn(i+1, "Commit message lines should be 72 characters or fewer.")
			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
}
