/*
 * Copyright 2015 Google Inc.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; version 2 of the License.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 */

package main

import (
	"bufio"
	"flag"
	"fmt"
	"log"
	"os"
	"os/exec"
	"regexp"
	"strings"
)

type subsystem struct {
	name       string
	maintainer []string
	paths      []string
	globs      []*regexp.Regexp
}

var subsystems []subsystem

func get_git_files() ([]string, error) {
	var files []string

	/* Read in list of all files in the git repository */
	cmd := exec.Command("git", "ls-files")
	out, err := cmd.StdoutPipe()
	if err != nil {
		log.Fatalf("git ls-files failed: %v", err)
		return files, err
	}
	if err := cmd.Start(); err != nil {
		log.Fatalf("Could not start %v: %v", cmd, err)
		return files, err
	}

	r := bufio.NewScanner(out)
	for r.Scan() {
		/* Cut out leading tab */
		files = append(files, r.Text())
	}

	cmd.Wait()

	return files, nil
}

func get_maintainers() ([]string, error) {
	var maintainers []string

	/* Read in all maintainers */
	file, err := os.Open("MAINTAINERS")
	if err != nil {
		log.Fatalf("Can't open MAINTAINERS file: %v", err)
		log.Fatalf("Are you running from the top-level directory?")
		return maintainers, err
	}
	defer file.Close()

	keep := false
	s := bufio.NewScanner(file)
	for s.Scan() {
		/* Are we in the "data" section and have a non-empty line? */
		if keep && s.Text() != "" {
			maintainers = append(maintainers, s.Text())
		}
		/* Skip everything before the delimiter */
		if s.Text() == "\t\t-----------------------------------" {
			keep = true
		}
	}

	return maintainers, nil
}

func path_to_regexstr(path string) string {
	// if prefix, allow all subdirectories
	if path[len(path)-1] == '/' {
		path += "*"
	}
	return glob_to_regex(path)
}

func path_to_regex(path string) *regexp.Regexp {
	regexstr := path_to_regexstr(path)
	return regexp.MustCompile(regexstr)
}

func build_maintainers(maintainers []string) {
	var current *subsystem
	for _, line := range maintainers {
		if line[1] != ':' {
			/* Create new subsystem entry */
			var tmp subsystem
			subsystems = append(subsystems, tmp)
			current = &subsystems[len(subsystems)-1]
			current.name = line
		} else {
			switch line[0] {
			case 'R', 'M':
				/* Add subsystem maintainer */
				current.maintainer = append(current.maintainer, line[3:len(line)])
			case 'F':
				// add files
				current.paths = append(current.paths, line[3:len(line)])
				current.globs = append(current.globs, path_to_regex(line[3:len(line)]))
				break
			case 'L', 'S', 'T', 'W': // ignore
			default:
				fmt.Println("No such specifier: ", line)
			}
		}
	}
}

func print_maintainers() {
	for _, subsystem := range subsystems {
		fmt.Println(subsystem.name)
		fmt.Println("  ", subsystem.maintainer)
		fmt.Println("  ", subsystem.paths)
	}
}

func match_file(fname string, component subsystem) bool {
	for _, glob := range component.globs {
		if glob.Match([]byte(fname)) {
			return true
		}
	}
	return false
}

func find_maintainer(fname string) {
	var success bool

	for _, subsystem := range subsystems {
		matched := match_file(fname, subsystem)
		if matched {
			success = true
			fmt.Println(fname, "is in subsystem",
				subsystem.name)
			fmt.Println("Maintainers: ", strings.Join(subsystem.maintainer, ", "))
		}
	}
	if !success {
		fmt.Println(fname, "has no subsystem defined in MAINTAINERS")
	}
}

func find_unmaintained(fname string) {
	var success bool

	for _, subsystem := range subsystems {
		matched := match_file(fname, subsystem)
		if matched {
			success = true
			fmt.Println(fname, "is in subsystem",
				subsystem.name)
		}
	}
	if !success {
		fmt.Println(fname, "has no subsystem defined in MAINTAINERS")
	}
}

// taken from https://github.com/zyedidia/glob/blob/master/glob.go which is
// Copyright (c) 2016: Zachary Yedidia.
// and was published under the MIT "Expat" license.
//
// only change: return the string, instead of a compiled golang regex
func glob_to_regex(glob string) string {
	regex := ""
	inGroup := 0
	inClass := 0
	firstIndexInClass := -1
	arr := []byte(glob)

	for i := 0; i < len(arr); i++ {
		ch := arr[i]

		switch ch {
		case '\\':
			i++
			if i >= len(arr) {
				regex += "\\"
			} else {
				next := arr[i]
				switch next {
				case ',':
					// Nothing
				case 'Q', 'E':
					regex += "\\\\"
				default:
					regex += "\\"
				}
				regex += string(next)
			}
		case '*':
			if inClass == 0 {
				regex += ".*"
			} else {
				regex += "*"
			}
		case '?':
			if inClass == 0 {
				regex += "."
			} else {
				regex += "?"
			}
		case '[':
			inClass++
			firstIndexInClass = i + 1
			regex += "["
		case ']':
			inClass--
			regex += "]"
		case '.', '(', ')', '+', '|', '^', '$', '@', '%':
			if inClass == 0 || (firstIndexInClass == i && ch == '^') {
				regex += "\\"
			}
			regex += string(ch)
		case '!':
			if firstIndexInClass == i {
				regex += "^"
			} else {
				regex += "!"
			}
		case '{':
			inGroup++
			regex += "("
		case '}':
			inGroup--
			regex += ")"
		case ',':
			if inGroup > 0 {
				regex += "|"
			} else {
				regex += ","
			}
		default:
			regex += string(ch)
		}
	}
	return "^" + regex + "$"
}

var is_email *regexp.Regexp

func extract_maintainer(maintainer string) string {
	if is_email == nil {
		is_email = regexp.MustCompile("<[^>]*>")
	}

	if match := is_email.FindStringSubmatch(maintainer); match != nil {
		return match[0][1 : len(match[0])-1]
	}
	return maintainer
}

func do_print_gerrit_rules() {
	for _, subsystem := range subsystems {
		if len(subsystem.paths) == 0 || len(subsystem.maintainer) == 0 {
			continue
		}
		fmt.Println("#", subsystem.name)
		for _, path := range subsystem.paths {
			fmt.Println("[filter \"file:\\\"" + path_to_regexstr(path) + "\\\"\"]")
			for _, maint := range subsystem.maintainer {
				fmt.Println("  reviewer =", extract_maintainer(maint))
			}
		}
		fmt.Println()
	}
}

func main() {
	var (
		files              []string
		err                error
		print_gerrit_rules = flag.Bool("print-gerrit-rules", false, "emit the MAINTAINERS rules in a format suitable for Gerrit's reviewers plugin")
		debug              = flag.Bool("debug", false, "emit additional debug output")
	)
	flag.Parse()

	/* get and build subsystem database */
	maintainers, err := get_maintainers()
	if err != nil {
		log.Fatalf("Oops.")
		return
	}
	build_maintainers(maintainers)

	if *debug {
		print_maintainers()
	}

	if *print_gerrit_rules {
		do_print_gerrit_rules()
		return
	}

	args := flag.Args()
	if len(args) == 0 {
		/* get the filenames */
		files, err = get_git_files()
		if err != nil {
			log.Fatalf("Oops.")
			return
		}
		for _, file := range files {
			find_unmaintained(file)
		}
	} else {
		files = args

		/* Find maintainers for each file */
		for _, file := range files {
			find_maintainer(file)
		}
	}
}
