// 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 (
	"encoding/xml"
	"fmt"
	"path/filepath"
	"regexp"
	"sort"
	"strconv"
	"strings"

	"v.io/jiri"
	"v.io/jiri/collect"
	"v.io/jiri/gitutil"
	"v.io/jiri/project"
	"v.io/jiri/tool"
	"v.io/x/devtools/tooldata"
	"v.io/x/lib/cmdline"
	"v.io/x/lib/set"
)

const (
	aliasesFileName = "aliases.v1.xml"
)

var (
	countFlag   bool
	aliasesFlag string
)

func init() {
	cmdContributorsList.Flags.BoolVar(&countFlag, "n", false, "Show number of contributions.")
	cmdContributorsList.Flags.StringVar(&aliasesFlag, "aliases", "", "Path to the aliases file.")
}

// cmdContributors represents the "jiri contributors" command.
var cmdContributors = &cmdline.Command{
	Name:     "contributors",
	Short:    "List project contributors",
	Long:     "List project contributors.",
	Children: []*cmdline.Command{cmdContributorsList},
}

// cmdContributorsList represents the "jiri contributors list" command.
var cmdContributorsList = &cmdline.Command{
	Runner: jiri.RunnerFunc(runContributorsList),
	Name:   "contributors",
	Short:  "List project contributors",
	Long: `
Lists project contributors. Projects to consider can be specified as
an argument. If no projects are specified, all projects in the current
manifest are considered by default.
`,
	ArgsName: "<projects>",
	ArgsLong: "<projects> is a list of projects to consider.",
}

type contributor struct {
	count int
	email string
	name  string
}

var (
	contributorRE = regexp.MustCompile("^(.*)\t(.*) <(.*)>$")
)

type aliasesSchema struct {
	XMLName xml.Name      `xml:"aliases"`
	Names   []nameSchema  `xml:"name"`
	Emails  []emailSchema `xml:"email"`
}

type nameSchema struct {
	Canonical string   `xml:"canonical"`
	Aliases   []string `xml:"alias"`
}

type emailSchema struct {
	Canonical string   `xml:"canonical"`
	Aliases   []string `xml:"alias"`
}

type aliasMaps struct {
	emails map[string]string
	names  map[string]string
}

func canonicalize(aliases *aliasMaps, email, name string) (string, string) {
	canonicalEmail, canonicalName := email, name
	if email, ok := aliases.emails[email]; ok {
		canonicalEmail = email
	}
	if name, ok := aliases.names[name]; ok {
		canonicalName = name
	}
	return canonicalEmail, canonicalName
}

func loadAliases(jirix *jiri.X) (*aliasMaps, error) {
	aliasesFile := aliasesFlag
	if aliasesFile == "" {
		dataDir, err := tooldata.DataDirPath(jirix, tool.Name)
		if err != nil {
			return nil, err
		}
		aliasesFile = filepath.Join(dataDir, aliasesFileName)
	}
	bytes, err := jirix.NewSeq().ReadFile(aliasesFile)
	if err != nil {
		return nil, err
	}
	var data aliasesSchema
	if err := xml.Unmarshal(bytes, &data); err != nil {
		return nil, fmt.Errorf("Unmarshal(%v) failed: %v", string(bytes), err)
	}
	aliases := &aliasMaps{
		emails: map[string]string{},
		names:  map[string]string{},
	}
	for _, email := range data.Emails {
		for _, alias := range email.Aliases {
			aliases.emails[alias] = email.Canonical
		}
	}
	for _, name := range data.Names {
		for _, alias := range name.Aliases {
			aliases.names[alias] = name.Canonical
		}
	}
	return aliases, nil
}

func runContributorsList(jirix *jiri.X, args []string) error {
	localProjects, err := project.LocalProjects(jirix, project.FastScan)
	if err != nil {
		return err
	}
	projectNames := map[string]struct{}{}
	if len(args) != 0 {
		projectNames = set.String.FromSlice(args)
	} else {
		for _, p := range localProjects {
			projectNames[p.Name] = struct{}{}
		}
	}

	aliases, err := loadAliases(jirix)
	if err != nil {
		return err
	}
	contributors := map[string]*contributor{}
	for name, _ := range projectNames {
		projects := localProjects.Find(name)
		if len(projects) == 0 {
			continue
		}

		for _, project := range projects {
			if err := jirix.NewSeq().Chdir(project.Path).Done(); err != nil {
				return err
			}
			switch project.Protocol {
			case "git":
				lines, err := listCommitters(jirix)
				if err != nil {
					return err
				}
				for _, line := range lines {
					matches := contributorRE.FindStringSubmatch(line)
					if got, want := len(matches), 4; got != want {
						return fmt.Errorf("unexpected length of %v: got %v, want %v", matches, got, want)
					}
					count, err := strconv.Atoi(strings.TrimSpace(matches[1]))
					if err != nil {
						return fmt.Errorf("Atoi(%v) failed: %v", strings.TrimSpace(matches[1]), err)
					}
					c := &contributor{
						count: count,
						email: strings.TrimSpace(matches[3]),
						name:  strings.TrimSpace(matches[2]),
					}
					if c.email == "jenkins.veyron@gmail.com" || c.email == "jenkins.veyron.rw@gmail.com" {
						continue
					}
					c.email, c.name = canonicalize(aliases, c.email, c.name)
					if existing, ok := contributors[c.name]; ok {
						existing.count += c.count
					} else {
						contributors[c.name] = c
					}
				}
			}
		}
	}
	names := []string{}
	for name, _ := range contributors {
		names = append(names, name)
	}
	sort.Strings(names)
	for _, name := range names {
		c := contributors[name]
		if countFlag {
			fmt.Fprintf(jirix.Stdout(), "%4d ", c.count)
		}
		fmt.Fprintf(jirix.Stdout(), "%v <%v>\n", c.name, c.email)
	}
	return nil
}

func listCommitters(jirix *jiri.X) (_ []string, e error) {
	branch, err := gitutil.New(jirix.NewSeq()).CurrentBranchName()
	if err != nil {
		return nil, err
	}
	stashed, err := gitutil.New(jirix.NewSeq()).Stash()
	if err != nil {
		return nil, err
	}
	if stashed {
		defer collect.Error(func() error { return gitutil.New(jirix.NewSeq()).StashPop() }, &e)
	}
	if err := gitutil.New(jirix.NewSeq()).CheckoutBranch("master"); err != nil {
		return nil, err
	}
	defer collect.Error(func() error { return gitutil.New(jirix.NewSeq()).CheckoutBranch(branch) }, &e)
	return gitutil.New(jirix.NewSeq()).Committers()
}

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