// 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.

package main

import (
	"fmt"
	"net/url"
	"sort"

	"v.io/jiri"
	"v.io/x/devtools/internal/test"
)

func gerritBaseUrl() (*url.URL, error) {
	u, err := url.Parse(gerritBaseUrlFlag)
	if err != nil {
		return nil, fmt.Errorf("invalid gerrit url %q: %v", gerritBaseUrlFlag, err)
	}
	return u, nil
}

func genStartPresubmitBuildLink(strRefs, strProjects, strTests string) string {
	return fmt.Sprintf("%s/%s/buildWithParameters?REFS=%s&PROJECTS=%s&TESTS=%s",
		jenkinsBaseJobUrl,
		presubmitTestJobFlag,
		url.QueryEscape(strRefs),
		url.QueryEscape(strProjects),
		url.QueryEscape(strTests))
}

// postMessage posts the given message to Gerrit.
func postMessage(jirix *jiri.X, message string, refs []string, success bool) error {
	refsUsingVerifiedLabel, err := getRefsUsingVerifiedLabel(jirix)
	if err != nil {
		return err
	}
	value := "1"
	if !success {
		value = "-" + value
	}
	for _, ref := range refs {
		labels := map[string]string{}
		if _, ok := refsUsingVerifiedLabel[ref]; ok {
			labels["Verified"] = value
		}
		gUrl, err := gerritBaseUrl()
		if err != nil {
			return err
		}
		if err := jirix.Gerrit(gUrl).PostReview(ref, message, labels); err != nil {
			return err
		}
		test.Pass(jirix.Context, "review posted for %q with labels %v.\n", ref, labels)
	}
	return nil
}

func getRefsUsingVerifiedLabel(jirix *jiri.X) (map[string]struct{}, error) {
	// Query all open CLs.
	gUrl, err := gerritBaseUrl()
	if err != nil {
		return nil, err
	}
	cls, err := jirix.Gerrit(gUrl).Query(defaultQueryString)
	if err != nil {
		return nil, err
	}

	// Identify the refs that use the "Verified" label.
	ret := map[string]struct{}{}
	for _, cl := range cls {
		if _, ok := cl.Labels["Verified"]; ok {
			ret[cl.Reference()] = struct{}{}
		}
	}

	return ret, nil
}

// getSubmittableCLs extracts CLs that have the AutoSubmit label in the commit
// message and satisfy all the submit rules. If a CL is part of a multi-part CLs
// set, all the CLs in that set need to be submittable. It returns a list of
// clLists each of which is either a single CL or a multi-part CLs set.
func getSubmittableCLs(jirix *jiri.X, cls clList) []clList {
	submittableCLs := []clList{}
	multiPartCLs := map[string]*multiPartCLSet{}
	for _, cl := range cls {
		// Check whether a CL satisfies all the submit rules. We do this by checking
		// the states of all its labels.
		//
		// cl.Labels has the following data structure:
		// {
		//   "Code-Review": {
		//     "approved": struct{}{},
		//   },
		//   "Verified": {
		//     "rejected": struct{}{},
		//   }
		//   ...
		// }
		// A label is satisfied/green when it has an "approved" entry.
		allLabelsApproved := true
		for label, labelData := range cl.Labels {
			// We only check the following labels which might not exist
			// at the same time.
			switch label {
			case "Code-Review", "Verified", "Non-Author-Code-Review", "To-Be-Reviewed":
				isApproved := false
				for state := range labelData {
					if state == "approved" {
						isApproved = true
						break
					}
				}
				if !isApproved {
					allLabelsApproved = false
					break
				}
			}
		}
		if cl.AutoSubmit && allLabelsApproved {
			if cl.MultiPart != nil {
				topic := cl.MultiPart.Topic
				if _, ok := multiPartCLs[topic]; !ok {
					multiPartCLs[topic] = NewMultiPartCLSet()
				}
				multiPartCLs[topic].addCL(cl)
			} else {
				submittableCLs = append(submittableCLs, clList{cl})
			}
		}
	}

	// This is to make sure we have consistent results order.
	sortedTopics := []string{}
	for topic := range multiPartCLs {
		sortedTopics = append(sortedTopics, topic)
	}
	sort.Strings(sortedTopics)

	// Find complete multi part cl sets.
	for _, topic := range sortedTopics {
		set := multiPartCLs[topic]
		if set.complete() {
			submittableCLs = append(submittableCLs, set.cls())
		}
	}

	return submittableCLs
}

// submitCLs submits the given CLs.
func submitCLs(jirix *jiri.X, cls clList) error {
	for _, cl := range cls {
		curRef := cl.Reference()
		msg := fmt.Sprintf("submit CL: %s\n", curRef)
		gUrl, err := gerritBaseUrl()
		if err != nil {
			return err
		}
		if err := jirix.Gerrit(gUrl).Submit(cl.Change_id); err != nil {
			test.Fail(jirix.Context, msg)
			fmt.Fprintf(jirix.Stderr(), "%v\n", err)
			if err := postMessage(jirix, fmt.Sprintf("Failed to submit CL:\n%v\n", err), []string{curRef}, true); err != nil {
				return err
			}
		} else {
			test.Pass(jirix.Context, msg)
		}
	}
	return nil
}

// testNameWithPartSuffix generates a new name from the given test name and part index.
func testNameWithPartSuffix(testName string, partIndex int) string {
	if partIndex < 0 {
		return testName
	}
	return fmt.Sprintf("%s-part%d", testName, partIndex)
}
