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

import (
	"encoding/json"
	"fmt"
	"io"
	"io/ioutil"
	"net/http"
	"net/url"
	"regexp"
	"strconv"
	"strings"

	"fuchsia.googlesource.com/jiri/collect"
)

func New(host string) (*Jenkins, error) {
	j := &Jenkins{
		host: host,
	}
	return j, nil
}

// NewForTesting creates a Jenkins instance in test mode.
func NewForTesting() *Jenkins {
	return &Jenkins{
		testMode:          true,
		invokeMockResults: map[string][]byte{},
	}
}

type Jenkins struct {
	host string

	// The following fields are for testing only.

	// testMode indicates whether this Jenkins instance is in test mode.
	testMode bool

	// invokeMockResults maps from API suffix to a mock result.
	// In test mode, the mock result will be returned when "invoke" is called.
	invokeMockResults map[string][]byte
}

// MockAPI mocks "invoke" with the given API suffix.
func (j *Jenkins) MockAPI(suffix, result string) {
	j.invokeMockResults[suffix] = []byte(result)
}

type QueuedBuild struct {
	Id     int
	Params string `json:"params,omitempty"`
	Task   QueuedBuildTask
}

type QueuedBuildTask struct {
	Name string
}

// ParseRefs parses refs from a QueuedBuild object's Params field.
func (qb *QueuedBuild) ParseRefs() string {
	// The params string is in the form of:
	// "\nREFS=ref/changes/12/3412/2\nPROJECTS=test" or
	// "\nPROJECTS=test\nREFS=ref/changes/12/3412/2"
	parts := strings.Split(qb.Params, "\n")
	refs := ""
	refsPrefix := "REFS="
	for _, part := range parts {
		if strings.HasPrefix(part, refsPrefix) {
			refs = strings.TrimPrefix(part, refsPrefix)
			break
		}
	}
	return refs
}

// QueuedBuilds returns the queued builds.
func (j *Jenkins) QueuedBuilds(jobName string) (_ []QueuedBuild, err error) {
	// Get queued builds.
	bytes, err := j.invoke("GET", "queue/api/json", url.Values{})
	if err != nil {
		return nil, err
	}
	var builds struct {
		Items []QueuedBuild
	}
	if err := json.Unmarshal(bytes, &builds); err != nil {
		return nil, fmt.Errorf("Unmarshal() failed: %v\n%s", err, string(bytes))
	}

	// Filter for jobName.
	queuedBuildsForJob := []QueuedBuild{}
	for _, build := range builds.Items {
		if build.Task.Name != jobName {
			continue
		}
		queuedBuildsForJob = append(queuedBuildsForJob, build)
	}
	return queuedBuildsForJob, nil
}

type BuildInfo struct {
	Actions   []BuildInfoAction
	Building  bool
	Number    int
	Result    string
	Id        string
	Timestamp int64
}

type BuildInfoAction struct {
	Parameters []BuildInfoParameter
}

type BuildInfoParameter struct {
	Name  string
	Value string
}

// ParseRefs parses the REFS parameter from a BuildInfo object.
func (bi *BuildInfo) ParseRefs() string {
	refs := ""
loop:
	for _, action := range bi.Actions {
		for _, param := range action.Parameters {
			if param.Name == "REFS" {
				refs = param.Value
				break loop
			}
		}
	}
	return refs
}

// OngoingBuilds returns a slice of BuildInfo for current ongoing builds
// for the given job.
func (j *Jenkins) OngoingBuilds(jobName string) (_ []BuildInfo, err error) {
	// Get urls of all ongoing builds.
	bytes, err := j.invoke("GET", "computer/api/json", url.Values{
		"tree": {"computer[executors[currentExecutable[url]],oneOffExecutors[currentExecutable[url]]]"},
	})
	if err != nil {
		return nil, err
	}
	var computers struct {
		Computer []struct {
			Executors []struct {
				CurrentExecutable struct {
					Url string
				}
			}
			OneOffExecutors []struct {
				CurrentExecutable struct {
					Url string
				}
			}
		}
	}
	if err := json.Unmarshal(bytes, &computers); err != nil {
		return nil, fmt.Errorf("Unmarshal() failed: %v\n%s", err, string(bytes))
	}
	urls := []string{}
	for _, computer := range computers.Computer {
		for _, executor := range computer.Executors {
			curUrl := executor.CurrentExecutable.Url
			if curUrl != "" {
				urls = append(urls, curUrl)
			}
		}
		for _, oneOffExecutor := range computer.OneOffExecutors {
			curUrl := oneOffExecutor.CurrentExecutable.Url
			if curUrl != "" {
				urls = append(urls, curUrl)
			}
		}
	}

	buildInfos := []BuildInfo{}
	masterJobURLRE := regexp.MustCompile(fmt.Sprintf(`.*/%s/(\d+)/$`, jobName))
	for _, curUrl := range urls {
		// Filter for jobName, and get the build number.
		matches := masterJobURLRE.FindStringSubmatch(curUrl)
		if matches == nil {
			continue
		}
		strBuildNumber := matches[1]
		buildNumber, err := strconv.Atoi(strBuildNumber)
		if err != nil {
			return nil, fmt.Errorf("Atoi(%s) failed: %v", strBuildNumber, err)
		}
		buildInfo, err := j.BuildInfo(jobName, buildNumber)
		if err != nil {
			return nil, err
		}
		buildInfos = append(buildInfos, *buildInfo)
	}
	return buildInfos, nil
}

// BuildInfo returns a build's info for the given jobName and buildNumber.
func (j *Jenkins) BuildInfo(jobName string, buildNumber int) (*BuildInfo, error) {
	buildSpec := fmt.Sprintf("%s/%d", jobName, buildNumber)
	return j.BuildInfoForSpec(buildSpec)
}

// BuildInfoWithBuildURL returns a build's info for the given build's URL.
func (j *Jenkins) BuildInfoForSpec(buildSpec string) (*BuildInfo, error) {
	getBuildInfoUri := fmt.Sprintf("job/%s/api/json", buildSpec)
	bytes, err := j.invoke("GET", getBuildInfoUri, url.Values{})
	if err != nil {
		return nil, err
	}
	var buildInfo BuildInfo
	if err := json.Unmarshal(bytes, &buildInfo); err != nil {
		return nil, fmt.Errorf("Unmarshal() failed: %v\n%s", err, string(bytes))
	}
	return &buildInfo, nil
}

// AddBuild adds a build to the given job.
func (j *Jenkins) AddBuild(jobName string) error {
	addBuildUri := fmt.Sprintf("job/%s/build", jobName)
	_, err := j.invoke("POST", addBuildUri, url.Values{})
	if err != nil {
		return err
	}
	return nil
}

// AddBuildWithParameter adds a parameterized build to the given job.
func (j *Jenkins) AddBuildWithParameter(jobName string, params url.Values) error {
	addBuildUri := fmt.Sprintf("job/%s/buildWithParameters", jobName)
	_, err := j.invoke("POST", addBuildUri, params)
	if err != nil {
		return err
	}
	return nil
}

// CancelQueuedBuild cancels the queued build by given id.
func (j *Jenkins) CancelQueuedBuild(id string) error {
	cancelQueuedBuildUri := "queue/cancelItem"
	if _, err := j.invoke("POST", cancelQueuedBuildUri, url.Values{
		"id": {id},
	}); err != nil {
		return err
	}
	return nil
}

// CancelOngoingBuild cancels the ongoing build by given jobName and buildNumber.
func (j *Jenkins) CancelOngoingBuild(jobName string, buildNumber int) error {
	cancelOngoingBuildUri := fmt.Sprintf("job/%s/%d/stop", jobName, buildNumber)
	if _, err := j.invoke("POST", cancelOngoingBuildUri, url.Values{}); err != nil {
		return err
	}
	return nil
}

type TestCase struct {
	ClassName string
	Name      string
	Status    string
}

func (t TestCase) Equal(t2 TestCase) bool {
	return t.ClassName == t2.ClassName && t.Name == t2.Name
}

// FailedTestCasesForBuildSpec returns failed test cases for the given build spec.
func (j *Jenkins) FailedTestCasesForBuildSpec(buildSpec string) ([]TestCase, error) {
	failedTestCases := []TestCase{}

	// Get all test cases.
	getTestReportUri := fmt.Sprintf("job/%s/testReport/api/json", buildSpec)
	bytes, err := j.invoke("GET", getTestReportUri, url.Values{})
	if err != nil {
		return failedTestCases, err
	}
	var testCases struct {
		Suites []struct {
			Cases []TestCase
		}
	}
	if err := json.Unmarshal(bytes, &testCases); err != nil {
		return failedTestCases, fmt.Errorf("Unmarshal(%v) failed: %v", string(bytes), err)
	}

	// Filter failed tests.
	for _, suite := range testCases.Suites {
		for _, curCase := range suite.Cases {
			if curCase.Status == "FAILED" || curCase.Status == "REGRESSION" {
				failedTestCases = append(failedTestCases, curCase)
			}
		}
	}
	return failedTestCases, nil
}

// JenkinsMachines stores information about Jenkins machines.
type JenkinsMachines struct {
	Machines []JenkinsMachine `json:"computer"`
}

// JenkinsMachine stores information about a Jenkins machine.
type JenkinsMachine struct {
	Name string `json:"displayName"`
	Idle bool   `json:"idle"`
}

// IsNodeIdle checks whether the given node is idle.
func (j *Jenkins) IsNodeIdle(node string) (bool, error) {
	bytes, err := j.invoke("GET", "computer/api/json", url.Values{})
	if err != nil {
		return false, err
	}
	machines := JenkinsMachines{}
	if err := json.Unmarshal(bytes, &machines); err != nil {
		return false, fmt.Errorf("Unmarshal() failed: %v\n%s\n", err, string(bytes))
	}
	for _, machine := range machines.Machines {
		if machine.Name == node {
			return machine.Idle, nil
		}
	}
	return false, fmt.Errorf("node %v not found", node)
}

// createRequest represents a request to create a new machine in
// Jenkins configuration.
type createRequest struct {
	Name              string            `json:"name"`
	Description       string            `json:"nodeDescription"`
	NumExecutors      int               `json:"numExecutors"`
	RemoteFS          string            `json:"remoteFS"`
	Labels            string            `json:"labelString"`
	Mode              string            `json:"mode"`
	Type              string            `json:"type"`
	RetentionStrategy map[string]string `json:"retentionStrategy"`
	NodeProperties    nodeProperties    `json:"nodeProperties"`
	Launcher          map[string]string `json:"launcher"`
}

// nodeProperties enumerates the environment variable settings for
// Jenkins configuration.
type nodeProperties struct {
	Class       string              `json:"stapler-class"`
	Environment []map[string]string `json:"env"`
}

// AddNodeToJenkins sends an HTTP request to Jenkins that prompts it
// to add a new machine to its configuration.
//
// NOTE: Jenkins REST API is not documented anywhere and the
// particular HTTP request used to add a new machine to Jenkins
// configuration has been crafted using trial and error.
func (j *Jenkins) AddNodeToJenkins(name, host, description, credentialsId string) error {
	request := createRequest{
		Name:              name,
		Description:       description,
		NumExecutors:      1,
		RemoteFS:          "/home/veyron/jenkins",
		Labels:            fmt.Sprintf("%s linux", name),
		Mode:              "EXCLUSIVE",
		Type:              "hudson.slaves.DumbSlave$DescriptorImpl",
		RetentionStrategy: map[string]string{"stapler-class": "hudson.slaves.RetentionStrategy$Always"},
		NodeProperties: nodeProperties{
			Class: "hudson.slaves.EnvironmentVariablesNodeProperty",
			Environment: []map[string]string{
				map[string]string{
					"stapler-class": "hudson.slaves.EnvironmentVariablesNodeProperty$Entry",
					"key":           "GOROOT",
					"value":         "$HOME/go",
				},
				map[string]string{
					"stapler-class": "hudson.slaves.EnvironmentVariablesNodeProperty$Entry",
					"key":           "PATH",
					"value":         "$HOME/go/bin:$PATH",
				},
				map[string]string{
					"stapler-class": "hudson.slaves.EnvironmentVariablesNodeProperty$Entry",
					"key":           "TERM",
					"value":         "xterm-256color",
				},
			},
		},
		Launcher: map[string]string{
			"stapler-class": "hudson.plugins.sshslaves.SSHLauncher",
			"host":          host,
			// The following ID can be retrieved from Jenkins configuration backup.
			"credentialsId": credentialsId,
		},
	}
	bytes, err := json.Marshal(request)
	if err != nil {
		return fmt.Errorf("Marshal(%v) failed: %v", request, err)
	}
	values := url.Values{
		"name": {name},
		"type": {"hudson.slaves.DumbSlave$DescriptorImpl"},
		"json": {string(bytes)},
	}
	_, err = j.invoke("GET", "computer/doCreateItem", values)
	if err != nil {
		return err
	}
	return nil
}

// RemoveNodeFromJenkins sends an HTTP request to Jenkins that prompts
// it to remove an existing machine from its configuration.
func (j *Jenkins) RemoveNodeFromJenkins(node string) error {
	_, err := j.invoke("POST", fmt.Sprintf("computer/%s/doDelete", node), url.Values{})
	if err != nil {
		return err
	}
	return nil
}

// invoke invokes the Jenkins API using the given suffix, values and
// HTTP method.
func (j *Jenkins) invoke(method, suffix string, values url.Values) (_ []byte, err error) {
	// Return mock result in test mode.
	if j.testMode {
		return j.invokeMockResults[suffix], nil
	}

	apiURL, err := url.Parse(j.host)
	if err != nil {
		return nil, fmt.Errorf("Parse(%q) failed: %v", j.host, err)
	}
	apiURL.Path = fmt.Sprintf("%s/%s", apiURL.Path, suffix)
	apiURL.RawQuery = values.Encode()
	var body io.Reader
	url, body := apiURL.String(), nil
	req, err := http.NewRequest(method, url, body)
	if err != nil {
		return nil, fmt.Errorf("NewRequest(%q, %q, %v) failed: %v", method, url, body, err)
	}
	req.Header.Add("Accept", "application/json")
	res, err := http.DefaultClient.Do(req)
	if err != nil {
		return nil, fmt.Errorf("Do(%v) failed: %v", req, err)
	}
	defer collect.Error(func() error { return res.Body.Close() }, &err)
	bytes, err := ioutil.ReadAll(res.Body)
	if err != nil {
		return nil, err
	}
	// queue/cancelItem API returns 404 even successful.
	// See: https://issues.jenkins-ci.org/browse/JENKINS-21311.
	if suffix != "queue/cancelItem" && res.StatusCode >= http.StatusBadRequest {
		return nil, fmt.Errorf("HTTP request %q returned %d:\n%s", url, res.StatusCode, string(bytes))
	}
	return bytes, nil
}

// GenBuildSpec returns a spec string for the given Jenkins build.
//
// If the main job is a multi-configuration job, the spec is in the form of:
// <jobName>/axis1Label=axis1Value,axis2Label=axis2Value,.../<suffix>
// The axis values are taken from the given axisValues map.
//
// If no axisValues are provides, the spec will be: <jobName>/<suffix>.
func GenBuildSpec(jobName string, axisValues map[string]string, suffix string) string {
	if len(axisValues) == 0 {
		return fmt.Sprintf("%s/%s", jobName, suffix)
	}

	parts := []string{}
	for k, v := range axisValues {
		parts = append(parts, fmt.Sprintf("%s=%s", k, v))
	}
	return fmt.Sprintf("%s/%s/%s", jobName, strings.Join(parts, ","), suffix)
}

// LastCompletedBuildStatus returns the most recent completed BuildInfo for the given job.
//
// axisValues can be set to nil if the job is not multi-configuration.
func (j *Jenkins) LastCompletedBuildStatus(jobName string, axisValues map[string]string) (*BuildInfo, error) {
	buildInfo, err := j.BuildInfoForSpec(GenBuildSpec(jobName, axisValues, "lastCompletedBuild"))
	if err != nil {
		return nil, err
	}
	return buildInfo, nil
}
