// 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 googlesource contains library functions for interacting with
// googlesource repository host.

package googlesource

import (
	"encoding/json"
	"fmt"
	"io/ioutil"
	"net/http"
	"net/url"
	"os"
	"path/filepath"
	"regexp"
	"strconv"
	"strings"
	"time"

	"fuchsia.googlesource.com/jiri"
)

// RepoStatus represents the status of a remote repository on googlesource.
type RepoStatus struct {
	Name        string            `json:"name"`
	CloneUrl    string            `json:"clone_url"`
	Description string            `json:"description"`
	Branches    map[string]string `json:"branches"`
}

// RepoStatuses is a map of repository name to RepoStatus.
type RepoStatuses map[string]RepoStatus

// parseCookie takes a single line from a cookie jar and parses it, returning
// an *http.Cookie.
func parseCookie(s string) (*http.Cookie, error) {
	// Cookiejar files have 7 tab-delimited fields.
	// See http://curl.haxx.se/mail/archive-2005-03/0099.html
	// 0: domain
	// 1: tailmatch
	// 2: path
	// 3: secure
	// 4: expires
	// 5: name
	// 6: value

	fields := strings.Fields(s)
	if len(fields) != 7 {
		return nil, fmt.Errorf("expected 7 fields but got %d: %q", len(fields), s)
	}
	expires, err := strconv.Atoi(fields[4])
	if err != nil {
		return nil, fmt.Errorf("invalid expiration: %q", fields[4])
	}

	cookie := &http.Cookie{
		Domain:  fields[0],
		Path:    fields[2],
		Secure:  fields[3] == "TRUE",
		Expires: time.Unix(int64(expires), 0),
		Name:    fields[5],
		Value:   fields[6],
	}
	return cookie, nil
}

// gitCookies attempts to read and parse cookies from the .gitcookies file in
// the users home directory.
func gitCookies(jirix *jiri.X) []*http.Cookie {
	cookies := []*http.Cookie{}

	homeDir := os.Getenv("HOME")
	if homeDir == "" {
		return cookies
	}

	cookieFile := filepath.Join(homeDir, ".gitcookies")
	bytes, err := jirix.NewSeq().ReadFile(cookieFile)
	if err != nil {
		return cookies
	}
	return parseCookieFile(jirix, bytes)
}

func parseCookieFile(jirix *jiri.X, bytes []byte) (cookies []*http.Cookie) {
	lines := strings.Split(string(bytes), "\n")

	for _, line := range lines {
		if strings.TrimSpace(line) == "" || line[0] == '#' {
			continue
		}
		cookie, err := parseCookie(line)
		if err != nil {
			fmt.Fprintf(jirix.Stderr(), "error parsing cookie in .gitcookies: %v\n", err)
		} else {
			cookies = append(cookies, cookie)
		}
	}
	return
}

// GetRepoStatuses returns the RepoStatus of all public projects hosted on the
// remote host.  Host must be a googlesource host.
//
// NOTE(nlacasse): Googlesource uses gitiles as its git repo browser.  gitiles
// has a completely undocumented feature that allows one to query the state of
// all repositories in a single request.  See "doGetJson" method in
// https://gerrit.googlesource.com/gitiles/+/master/gitiles-servlet/src/main/java/com/google/gitiles/RepositoryIndexServlet.java
//
// It's possible that gitiles will stop responding to this request at some
// future version, or that googlesource will move away from gitiles entirely.
// If that happens we can still get all the repo information in one request by
// using the /projects/ endpoint on Gerrit.  See
// https://review.typo3.org/Documentation/rest-api-projects.html#list-projects
func GetRepoStatuses(jirix *jiri.X, host string, branches []string) (RepoStatuses, error) {
	u, err := url.Parse(host)
	if err != nil {
		return nil, err
	}
	if u.Scheme != "http" && u.Scheme != "https" {
		return nil, fmt.Errorf("remote host scheme is not http(s): %s", host)
	}

	u.Path = "/"
	q := u.Query()
	q.Set("format", "json")
	for _, b := range branches {
		q.Add("show-branch", b)
	}
	u.RawQuery = q.Encode()

	req, err := http.NewRequest("GET", u.String(), nil)
	if err != nil {
		return nil, fmt.Errorf("NewRequest(%q, %q, %v) failed: %v", "GET", u.String(), nil, err)
	}
	for _, c := range gitCookies(jirix) {
		req.AddCookie(c)
	}
	resp, err := http.DefaultClient.Do(req)
	if err != nil {
		return nil, fmt.Errorf("Do(%v) failed: %v", req, err)
	}
	defer resp.Body.Close()
	body, err := ioutil.ReadAll(resp.Body)
	if resp.StatusCode != http.StatusOK {
		return nil, fmt.Errorf("got status code %v fetching %s: %s", resp.StatusCode, host, string(body))
	}

	// body has leading ")]}'" to prevent js hijacking.  We must trim it.
	trimmedBody := strings.TrimPrefix(string(body), ")]}'")

	repoStatuses := make(RepoStatuses)
	if err := json.Unmarshal([]byte(trimmedBody), &repoStatuses); err != nil {
		return nil, fmt.Errorf("Unmarshal(%v) failed: %v", trimmedBody, err)
	}
	return repoStatuses, nil
}

var googleSourceRemoteRegExp = regexp.MustCompile(`(?i)https?://.*\.googlesource.com.*`)

// IsGoogleSourceRemote returns true if the host url is a googlesource remote.
func IsGoogleSourceRemote(host string) bool {
	return googleSourceRemoteRegExp.MatchString(host)
}
