// Copyright 2021 The Tint Authors.
//
// 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.

// gerrit-stats gathers statistics about changes made to Tint.
package main

import (
	"flag"
	"fmt"
	"io/ioutil"
	"net/url"
	"os"
	"regexp"
	"strings"
	"time"

	"github.com/andygrunwald/go-gerrit"
)

const (
	yyyymmdd  = "2006-01-02"
	gerritURL = "https://dawn-review.googlesource.com/"
)

var (
	// See https://dawn-review.googlesource.com/new-password for obtaining
	// username and password for gerrit.
	gerritUser  = flag.String("gerrit-user", "", "gerrit authentication username")
	gerritPass  = flag.String("gerrit-pass", "", "gerrit authentication password")
	repoFlag    = flag.String("repo", "tint", "the project (tint or dawn)")
	userFlag    = flag.String("user", "", "user name / email")
	afterFlag   = flag.String("after", "", "start date")
	beforeFlag  = flag.String("before", "", "end date")
	daysFlag    = flag.Int("days", 182, "interval in days (used if --after is not specified)")
	verboseFlag = flag.Bool("v", false, "verbose mode - lists all the changes")
)

func main() {
	flag.Parse()
	if err := run(); err != nil {
		fmt.Fprintln(os.Stderr, err)
		os.Exit(1)
	}
}

func queryChanges(client *gerrit.Client, queryParts ...string) ([]gerrit.ChangeInfo, string, error) {
	query := strings.Join(queryParts, "+")
	out := []gerrit.ChangeInfo{}
	for {
		changes, _, err := client.Changes.QueryChanges(&gerrit.QueryChangeOptions{
			QueryOptions: gerrit.QueryOptions{Query: []string{query}},
			Skip:         len(out),
		})
		if err != nil {
			return nil, "", err
		}

		out = append(out, *changes...)
		if len(*changes) == 0 || !(*changes)[len(*changes)-1].MoreChanges {
			break
		}
	}
	return out, query, nil
}

func run() error {
	var after, before time.Time
	var err error
	user := *userFlag
	if user == "" {
		return fmt.Errorf("Missing required 'user' flag")
	}
	if *beforeFlag != "" {
		before, err = time.Parse(yyyymmdd, *beforeFlag)
		if err != nil {
			return fmt.Errorf("Couldn't parse before date: %w", err)
		}
	} else {
		before = time.Now()
	}
	if *afterFlag != "" {
		after, err = time.Parse(yyyymmdd, *afterFlag)
		if err != nil {
			return fmt.Errorf("Couldn't parse after date: %w", err)
		}
	} else {
		after = before.Add(-time.Hour * time.Duration(24**daysFlag))
	}

	client, err := gerrit.NewClient(gerritURL, nil)
	if err != nil {
		return fmt.Errorf("Couldn't create gerrit client: %w", err)
	}

	if *gerritUser == "" {
		cookiesFile := os.Getenv("HOME") + "/.gitcookies"
		if cookies, err := ioutil.ReadFile(cookiesFile); err == nil {
			re := regexp.MustCompile(`dawn-review.googlesource.com\s+(?:FALSE|TRUE)[\s/]+(?:FALSE|TRUE)\s+[0-9]+\s+.\s+(.*)=(.*)`)
			match := re.FindStringSubmatch(string(cookies))
			if len(match) == 3 {
				*gerritUser, *gerritPass = match[1], match[2]
			}
		}
	}

	if *gerritUser != "" {
		client.Authentication.SetBasicAuth(*gerritUser, *gerritPass)
	}

	submitted, submittedQuery, err := queryChanges(client,
		"status:merged",
		"owner:"+user,
		"after:"+date(after),
		"before:"+date(before),
		"repo:"+*repoFlag)
	if err != nil {
		if *gerritUser == "" {
			return fmt.Errorf(`Query failed, possibly because of authentication.
See https://dawn-review.googlesource.com/new-password for obtaining a username
and password which can be provided with --gerrit-user and --gerrit-pass.
%w`, err)
		}
		return fmt.Errorf("Query failed: %w", err)
	}

	reviewed, reviewQuery, err := queryChanges(client,
		"commentby:"+user,
		"-owner:"+user,
		"after:"+date(after),
		"before:"+date(before),
		"repo:"+*repoFlag)
	if err != nil {
		return fmt.Errorf("Query failed: %w", err)
	}

	ignorelist := []*regexp.Regexp{
		regexp.MustCompile("Revert .*"),
	}
	ignore := func(s string) bool {
		for _, re := range ignorelist {
			if re.MatchString(s) {
				return true
			}
		}
		return false
	}

	insertions, deletions := 0, 0
	for _, change := range submitted {
		if ignore(change.Subject) {
			continue
		}
		insertions += change.Insertions
		deletions += change.Deletions
	}

	fmt.Printf("Between %v and %v, %v:\n", date(after), date(before), user)
	fmt.Printf("  Submitted %v changes (LOC: %v+, %v-) \n", len(submitted), insertions, deletions)
	fmt.Printf("  Reviewed %v changes\n", len(reviewed))
	fmt.Printf("\n")

	if *verboseFlag {
		fmt.Printf("Submitted changes:\n")
		for i, change := range submitted {
			fmt.Printf("%3.1v: %6.v %v (LOC: %v+, %v-)\n", i, change.Number, change.Subject, change.Insertions, change.Deletions)
		}
		fmt.Printf("\n")
		fmt.Printf("Reviewed changes:\n")
		for i, change := range reviewed {
			fmt.Printf("%3.1v: %6.v %v (LOC: %v+, %v-)\n", i, change.Number, change.Subject, change.Insertions, change.Deletions)
		}
	}

	fmt.Printf("\n")
	fmt.Printf("Submitted query: %vq/%v\n", gerritURL, url.QueryEscape(submittedQuery))
	fmt.Printf("Review query: %vq/%v\n", gerritURL, url.QueryEscape(reviewQuery))

	return nil
}

func today() time.Time {
	return time.Now()
}

func date(t time.Time) string {
	return t.Format(yyyymmdd)
}
