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

	"v.io/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)
}
