// package travisci provides a library for interacting with the Github app
// Travis CI via it's API: https://docs.travis-ci.com/api/#api-v3
//
// Authentication is done using a travis access token as described in
// https://docs.travis-ci.com/api/#authentication

package travisci

import (
	"context"
	"encoding/json"
	"fmt"
	"io"
	"net/http"
	"net/url"
	"strconv"

	"go.skia.org/infra/go/httputils"
	"go.skia.org/infra/go/util"
)

const (
	TRAVIS_API_URL     = "https://api.travis-ci.org"
	TRAVIS_API_VERSION = "3"

	BUILD_STATE_CREATED = "created"
	BUILD_STATE_PASSED  = "passed"
	BUILD_STATE_FAILED  = "failed"

	FETCH_PULL_REQUESTS_LIMIT = 100
)

// TravisCI is an object used for iteracting with the Travis CI V3 API.
// Docs are here: https://docs.travis-ci.com/api/#api-v3
type TravisCI struct {
	client    *http.Client
	ctx       context.Context
	repoOwner string
	repoName  string
	apiURL    string
	token     string
}

type Builds struct {
	Builds []*Build `json:"builds"`
}

type Build struct {
	Id                int    `json:"id"`
	Duration          int    `json:"duration"`
	State             string `json:"state"`
	StartedAt         string `json:"started_at"`
	PullRequestNumber int    `json:"pull_request_number"`
}

// NewTravisCI returns a new TravisCI instance.
func NewTravisCI(ctx context.Context, repoOwner, repoName, accessToken string) (*TravisCI, error) {
	return &TravisCI{
		client:    httputils.NewTimeoutClient(),
		ctx:       ctx,
		repoOwner: repoOwner,
		repoName:  repoName,
		apiURL:    TRAVIS_API_URL,
		token:     accessToken,
	}, nil
}

func (t *TravisCI) GetPullRequestBuilds(pullNumber int, createdBy string) ([]*Build, error) {
	params := url.Values{}
	params.Add("limit", strconv.Itoa(FETCH_PULL_REQUESTS_LIMIT))
	params.Add("sort_by", "id:desc")
	params.Add("event_type", "pull_request")
	params.Add("created_by", createdBy)
	repositorySlug := fmt.Sprintf("%s/%s", t.repoOwner, t.repoName)
	suburl := fmt.Sprintf("/repo/%s/builds?%s", url.QueryEscape(repositorySlug), params.Encode())

	builds := &Builds{}
	if err := t.get(suburl, builds); err != nil {
		return nil, fmt.Errorf("API call to %s failed: %s", suburl, err)
	}
	pullRequestBuilds := []*Build{}
	for _, build := range builds.Builds {
		if build.PullRequestNumber == pullNumber {
			pullRequestBuilds = append(pullRequestBuilds, build)
		}
	}
	return pullRequestBuilds, nil
}

func (t *TravisCI) GetBuildURL(buildID int) string {
	return fmt.Sprintf("https://travis-ci.org/flutter/engine/builds/%d", buildID)
}

// get retrieves the given suburl and populates 'rv' with the result.
func (t *TravisCI) get(suburl string, rv interface{}) error {
	getURL := t.apiURL + suburl
	req, err := http.NewRequest("GET", getURL, nil)
	if err != nil {
		return err
	}
	req.Header.Set("Travis-API-Version", TRAVIS_API_VERSION)
	req.Header.Set("Authorization", fmt.Sprintf("token %s", t.token))

	resp, err := t.client.Do(req)
	if err != nil {
		return fmt.Errorf("Failed to GET %s: %s", getURL, err)
	}
	if resp.StatusCode == http.StatusNotFound {
		return fmt.Errorf("Build not found: %s", getURL)
	}
	if resp.StatusCode >= http.StatusBadRequest {
		return fmt.Errorf("Error retrieving %s: %d %s", getURL, resp.StatusCode, resp.Status)
	}
	defer util.Close(resp.Body)
	body, err := io.ReadAll(resp.Body)
	if err != nil {
		return fmt.Errorf("Could not read response body: %s", err)
	}
	if err := json.Unmarshal(body, &rv); err != nil {
		return fmt.Errorf("Failed to decode JSON: %s", err)
	}
	return nil
}
