// Copyright 2018 The Fuchsia 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 gerrit

import (
	"bufio"
	"bytes"
	"errors"
	"fmt"
	"io/ioutil"
	"net/http"
	"net/http/cookiejar"
	"net/url"
	"os"
	"path"
	"strconv"
	"strings"
	"sync"
	"time"

	"fuchsia.googlesource.com/jiri"
	"fuchsia.googlesource.com/jiri/gitutil"
	"golang.org/x/net/publicsuffix"
)

const (
	cookieHTTPOnlyPrefix = "#HttpOnly_"
	generatePasswordURL  = "https://%s/new-password"
	ssoCookieAge         = 30 * 24 * time.Hour // cookie expiration time from HTTP response
	ssoCookieLife        = 20 * time.Hour      // actual cookie expiration time according to documentation
)

var (
	ErrRedirectOnGerrit       = errors.New("got redirection while downloading file from gerrit server")
	ErrRedirectOnGerritSSO    = errors.New("got redirection while downloading file from gerrit server using SSO cookie")
	ErrCookieNotExist         = errors.New("cookie file not found")
	ErrSSOPathNotSet          = errors.New("master SSO cookie path is not set, please run \"jiri init --sso-cookie-path PATH_TO_SSO\" and try again")
	ErrSSOCookieExpireInvalid = errors.New("SSO cookie is either invalid or expired, please run \"glogin\" and try again")
	ErrHTTPForbidden          = errors.New("server return HTTP 403, cookies are not accepted")

	ssoCookiePath      = "" // path to user master SSO cookie
	ssoCookieCachePath = "" // path to jiri managed SSO cookie cache
	bootstrapOnce      sync.Once
)

// The golang cookiejar implementation will remove the domain name, expiration
// time etc. from the cookies returned from Cookies(*url.URL) method (maybe for
// security reasons). The expiration time is crucial for caching the sso
// cookies, therefore we build our own cookiejar to save a copy of unstripped
// SSO cookie.
type ssoCookieJar struct {
	jar        http.CookieJar
	ssoCookies map[string]*http.Cookie
}

// BootstrapGerritSSO will setup cookie cache for SSO cookies and setup the
// path for master SSO cookie. Due to security concerns, we cannot hard code sso
// cookie paths in jiri, instead, we ask user to supply path to master sso
// cookie path using "jiri init --sso-cookie-path" command.
func BootstrapGerritSSO(jirix *jiri.X) {
	bootstrapOnce.Do(func() {
		ssoCookiePath = jirix.SsoCookiePath
		ssoCookieCachePath = path.Join(jirix.RootMetaDir(), "jiricookies.txt")
	})
}

// newSSOCookieJar constructs a new ssoCookieJar instance. Based on golang
// cookiejar implementation, the error will always be nil.
func newSSOCookieJar() (*ssoCookieJar, error) {
	j, err := cookiejar.New(&cookiejar.Options{PublicSuffixList: publicsuffix.List})
	if err != nil {
		return nil, err
	}
	return &ssoCookieJar{
		jar:        j,
		ssoCookies: make(map[string]*http.Cookie),
	}, nil
}

// SetCookies overrides cookiejar.SetCookies method, which implements the
// SetCookies method of the http.CookieJar interface. It does nothing if
// the URL's scheme is not HTTP or HTTPS.
func (j *ssoCookieJar) SetCookies(u *url.URL, cookies []*http.Cookie) {
	// Save/update SSO cookies
	for _, cookie := range cookies {
		if cookie.Name == "SSO" {
			if j.ssoCookies[u.Host] == nil || j.ssoCookies[u.Host].Expires.Before(cookie.Expires) {
				j.ssoCookies[u.Host] = cookie
			}
		}
	}
	j.jar.SetCookies(u, cookies)
}

// Cookies overrides cookiejar.Cookies method, which implements the Cookies
// method of the http.CookieJar interface. It returns an empty slice if the
// URL's scheme is not HTTP or HTTPS.
func (j *ssoCookieJar) Cookies(u *url.URL) (cookies []*http.Cookie) {
	return j.jar.Cookies(u)
}

// GetSSOCookie will return saved SSO cookie for url u. It will return nil
// if that cookie does not exist.
func (j *ssoCookieJar) GetSSOCookie(u *url.URL) (cookie *http.Cookie) {
	return j.ssoCookies[u.Host]
}

// FetchFile downloads a file and returns its content to a byte slice. It will
// return ErrRedirectOnGerrit if redirection is detected, which indicates that
// user authentication is required.
func FetchFile(gerritHost, path string) ([]byte, error) {
	client := &http.Client{
		CheckRedirect: func(req *http.Request, via []*http.Request) error {
			return http.ErrUseLastResponse
		},
	}
	downloadPath := gerritHost + path
	resp, err := client.Get(downloadPath)
	if err != nil {
		return nil, err
	}
	defer resp.Body.Close()
	// Check if there is an redirection
	if resp.StatusCode != http.StatusOK {
		if _, err := resp.Location(); err == nil {
			return nil, ErrRedirectOnGerrit
		}
		return nil, fmt.Errorf("expecting status code %d from %q, got %d ", http.StatusOK, downloadPath, resp.StatusCode)
	}
	return ioutil.ReadAll(resp.Body)
}

func fetchFileWithJar(jirix *jiri.X, gerritHost, path string, jar http.CookieJar) ([]byte, error) {
	hostName := gerritHost[len("https://"):]
	client := &http.Client{
		Jar: jar,
	}
	downloadPath := gerritHost + path
	resp, err := client.Get(downloadPath)
	if err != nil {
		return nil, err
	}

	if resp.Request != nil {
		if resp.Request.URL.Host != hostName {
			// If final request have different hostname than gerritHost
			// It indicates gerrit SSO cookie is either invalid or expired
			return nil, ErrRedirectOnGerritSSO
		}
	}
	defer resp.Body.Close()
	if resp.StatusCode != http.StatusOK {
		// Unexpected response from server, log HTTP headers.
		if jirix != nil {
			jirix.Logger.Debugf("got HTTP %d when accessing %q", resp.StatusCode, downloadPath)
			jirix.Logger.Debugf(dumpHeaders(resp))
		}
		if resp.StatusCode == http.StatusForbidden {
			return nil, ErrHTTPForbidden
		}
		return nil, fmt.Errorf("expecting status code %d from %q, got %d ", http.StatusOK, downloadPath, resp.StatusCode)
	}
	return ioutil.ReadAll(resp.Body)
}

func dumpHeaders(resp *http.Response) string {
	var output bytes.Buffer

	header := resp.Request.Header
	if header != nil {
		output.WriteString("HTTP Request Header:\n")
		for k, v := range header {
			output.WriteString(fmt.Sprintf("\t%s: %v\n", k, v))
		}
	}

	header = resp.Header
	if header != nil {
		output.WriteString("\nHTTP Response Header:\n")
		for k, v := range header {
			output.WriteString(fmt.Sprintf("\t%s: %v\n", k, v))
		}
	}
	output.WriteByte('\n')

	return output.String()
}

// FetchFileSSO downloads a file from a gerrit host that requires SSO login
// and returns its content to a byte slice. Since it uses user's master SSO
// cookie, the scheme of the url should always be HTTPS, otherwise an error
// will be returned.
func FetchFileSSO(jirix *jiri.X, gerritHost, path string) ([]byte, error) {
	BootstrapGerritSSO(jirix)
	if !strings.HasPrefix(gerritHost, "https://") {
		return nil, fmt.Errorf("Unsupported scheme for host %q", gerritHost)
	}
	hostName := gerritHost[len("https://"):]

	fetcher := func(jirix *jiri.X, cookieCache, gerritHost string, cookieType CookieType) ([]byte, *ssoCookieJar, error) {
		jar, err := LoadCookies(jirix, cookieCache, hostName, cookieType)
		if err != nil {
			return nil, nil, err
		}
		data, err := fetchFileWithJar(jirix, gerritHost, path, jar)
		return data, jar, err
	}

	cookieType := GitCookieOnly
	var data []byte
	var jar *ssoCookieJar
	var err error
	for data, jar, err = fetcher(jirix, ssoCookieCachePath, gerritHost, cookieType); err != nil; {
		switch cookieType {
		case SiteSSO, MasterSSO:
			jirix.Logger.Debugf("failed to fetch %s%s using sso cookies", gerritHost, path)
		case GitCookieOnly:
			jirix.Logger.Debugf("failed to fetch %s%s using git cookies", gerritHost, path)
		}

		switch err {
		case ErrHTTPForbidden:
			if cookieType == GitCookieOnly {
				return nil, fmt.Errorf("git cookies for %s are invalid, please follow the instructions at %q to refresh your git cookies", gerritHost, fmt.Sprintf(generatePasswordURL, hostName))
			}
			// Unexpected access deny when using cookies other than git cookies. Report the error.
			return nil, fmt.Errorf("access to %s%s is denied. Got HTTP 403 error from the server", gerritHost, path)

		case ErrRedirectOnGerritSSO:
			if cookieType == GitCookieOnly {
				cookieType = SiteSSO
				continue
			}
			if cookieType == SiteSSO {
				cookieType = MasterSSO
				continue
			}
			// cookieType == MasterSSO
			// It generally means both gerrit SSO cookie and
			// master SSO cookies are both exipred, ask user to refresh
			// cookies
			return nil, ErrSSOCookieExpireInvalid

		default:
			return nil, err
		}
	}

	// Succesfully fetched the target file
	switch cookieType {
	case SiteSSO, MasterSSO:
		jirix.Logger.Debugf("fetched %s:%s using sso cookies", gerritHost, path)
		// Cache the SSO cookies if the file is fetched using SSO cookies
		if err := CacheCookies(ssoCookieCachePath, hostName, jar); err != nil {
			return nil, err
		}

	case GitCookieOnly:
		jirix.Logger.Debugf("fetched %s:%s using git cookies", gerritHost, path)
	}

	return data, nil
}

// UnmarshalNSCookieData parses the Netscape-format cookies from
// data and return a slice of golang cookies.
func UnmarshalNSCookieData(data []byte) ([]*http.Cookie, error) {
	var cookieBuf bytes.Buffer
	if _, err := cookieBuf.Write(data); err != nil {
		return nil, err
	}

	cookieScanner := bufio.NewScanner(&cookieBuf)
	returnList := make([]*http.Cookie, 0)
	for cookieScanner.Scan() {
		currLine := strings.TrimSpace(cookieScanner.Text())
		fields := strings.Fields(currLine)
		// Skip unrelated lines
		if len(fields) != 7 {
			continue
		}
		cookie := &http.Cookie{}
		if strings.HasPrefix(fields[0], cookieHTTPOnlyPrefix) {
			cookie.Domain = fields[0][len(cookieHTTPOnlyPrefix):]
			cookie.HttpOnly = true
		} else {
			cookie.Domain = fields[0]
		}
		cookie.Path = fields[2]
		secure, err := strconv.ParseBool(fields[3])
		if err != nil {
			return nil, err
		}
		cookie.Secure = secure
		timestamp, err := strconv.ParseInt(fields[4], 10, 64)
		if err != nil {
			return nil, err
		}
		cookie.Expires = time.Unix(timestamp, 0)
		cookie.Name = fields[5]
		cookie.Value = fields[6]
		returnList = append(returnList, cookie)
	}
	return returnList, nil
}

// MarshalNSCookieData packs the slice of golang cookies into
// the Netscape-format cookies.
func MarshalNSCookieData(cookies []*http.Cookie) ([]byte, error) {
	var cookieBuf bytes.Buffer
	if cookies == nil || len(cookies) == 0 {
		return cookieBuf.Bytes(), nil
	}

	for _, cookie := range cookies {
		var builder strings.Builder
		if cookie.HttpOnly {
			builder.WriteString(cookieHTTPOnlyPrefix + cookie.Domain)
		} else {
			builder.WriteString(cookie.Domain)
		}
		builder.WriteRune('\t')
		builder.WriteString("FALSE")
		builder.WriteRune('\t')
		if cookie.Path != "" {
			builder.WriteString(cookie.Path)
		} else {
			builder.WriteString("/")
		}
		builder.WriteRune('\t')
		if cookie.Secure {
			builder.WriteString("TRUE")
		} else {
			builder.WriteString("FALSE")
		}
		builder.WriteRune('\t')
		builder.WriteString(strconv.FormatInt(cookie.Expires.Unix(), 10))
		builder.WriteRune('\t')
		builder.WriteString(cookie.Name)
		builder.WriteRune('\t')
		builder.WriteString(cookie.Value)
		builder.WriteRune('\n')
		if _, err := cookieBuf.WriteString(builder.String()); err != nil {
			return nil, err
		}
	}
	return cookieBuf.Bytes(), nil
}

func loadJiriCookies(jiriCookiePath string) []*http.Cookie {
	jiriCookieData, err := ioutil.ReadFile(jiriCookiePath)
	if err != nil {
		return nil
	}

	cookies, err := UnmarshalNSCookieData(jiriCookieData)
	if err != nil {
		return nil
	}
	return cookies
}

// CookieType specifies the type of cookies should be loaded by LoadCookies
// function.
type CookieType int

const (
	// GitCookieOnly specifies that only git cookies should be loaded by
	// LoadCookies function.
	GitCookieOnly CookieType = iota
	// SiteSSO specifies that site SSO cookie should be loaded from jiri
	// cookie cache by LoadCookies function. If it is not found or experied,
	// The combination of master SSO and git cookies should be loaded.
	SiteSSO
	// MasterSSO specifies that the combination of master SSO and git cookies
	// should be loaded by LoadCookies function regardless of the status of
	// site SSO cookie.
	MasterSSO
)

// LoadCookies loads necessary cookies from various sources (master sso,
// gitcookies and cached jiricookies), returning a cookiejar that contains
// necessary cookies to login to the hostName. An error will be returned
// if no suitable cookie is found or if there is an I/O error.
func LoadCookies(jirix *jiri.X, jiriCookiePath, hostName string, cookieType CookieType) (*ssoCookieJar, error) {
	cookieJar, err := newSSOCookieJar()

	// Read jiriCookiePath, it may have cached cookies for gerrit host
	if cookieType == SiteSSO {
		cachedSSOCookies := loadJiriCookies(jiriCookiePath)
		var cachedSSOCookie *http.Cookie
		if cachedSSOCookies != nil {
			for _, cookie := range cachedSSOCookies {
				if cookie.Name == "SSO" && cookie.Domain == hostName {
					if cookie.Expires.After(time.Now()) {
						cachedSSOCookie = cookie
						break
					}
				}
			}
		}
		if cachedSSOCookie != nil {
			cookieJar.SetCookies(&url.URL{
				Scheme: "https",
				Host:   cachedSSOCookie.Domain,
				Path:   "/",
			}, []*http.Cookie{cachedSSOCookie})
			return cookieJar, nil
		}
	}

	// Load master SSO if site SSO cookie is not found and cookieType
	// is not GitCookieOnly.
	if cookieType != GitCookieOnly {
		ssoPath, err := getSSOCookiePath()
		if err != nil {
			if err == ErrCookieNotExist {
				return nil, ErrSSOCookieExpireInvalid
			}
			return nil, err
		}
		ssoCookie, err := readMasterSSOCookie(ssoPath)
		if err != nil {
			return nil, err
		}
		if loginRequired(ssoCookie) {
			return nil, ErrSSOCookieExpireInvalid
		}
		cookieJar.SetCookies(&url.URL{
			Scheme: "https",
			Host:   ssoCookie.Domain,
			Path:   "/",
		}, []*http.Cookie{ssoCookie})
	}

	// Read .gitcookies
	gitCookiePath, err := getCookiePath(jirix)
	if err != nil {
		if err == ErrCookieNotExist {
			return nil, fmt.Errorf("git cookies not found, please follow the instructions at %q", fmt.Sprintf(generatePasswordURL, hostName))
		}
		return nil, err
	}
	gitCookieData, err := ioutil.ReadFile(gitCookiePath)
	if err != nil {
		return nil, err
	}
	cookies, err := UnmarshalNSCookieData(gitCookieData)

	// Looking for git cookies for gerrit Host
	var gerritGitCookie *http.Cookie
	for _, cookie := range cookies {
		if cookie.Domain == hostName && cookie.Name == "o" && strings.HasPrefix(cookie.Value, "git") {
			gerritGitCookie = cookie
			// Always load last git cookies as the last one is the latest one in git cookie file.
		}
	}

	if gerritGitCookie == nil {
		return nil, fmt.Errorf("cookie for %q is not found in git cookies, please follow the instructions at %q", hostName, fmt.Sprintf(generatePasswordURL, hostName))
	}
	cookieJar.SetCookies(&url.URL{
		Scheme: "https",
		Host:   gerritGitCookie.Domain,
		Path:   "/",
	}, []*http.Cookie{gerritGitCookie})
	return cookieJar, nil
}

// CacheCookies saves the gerrit SSO cookie back jiriCookiePath file.
// As there is a limit on how many SSO cookies can be requested per hour,
// caching the gerrit SSO cookie allows jiri to avoid hitting the limiter.
func CacheCookies(jiriCookiePath, hostName string, cookiejar *ssoCookieJar) error {
	// Read the cache first
	var cookies []*http.Cookie
	cookies = loadJiriCookies(jiriCookiePath)
	if cookies == nil {
		cookies = make([]*http.Cookie, 0)
	}
	// Retrieve latest gerrit SSO cookie from jar
	latestSSOCookie := cookiejar.GetSSOCookie(&url.URL{
		Scheme: "https",
		Path:   "/",
		Host:   hostName,
	})
	if latestSSOCookie == nil {
		return errors.New("gerrit SSO cookie not found in cookie jar")
	}
	latestSSOCookie.Domain = hostName
	latestSSOCookie.Path = "/"
	var gerritSSOCookieExists bool
	for i, cookie := range cookies {
		if cookie.Name == latestSSOCookie.Name && cookie.Domain == latestSSOCookie.Domain {
			gerritSSOCookieExists = true
			// Only replace the cookie if the cached cookie expires earlier than latestSSOCookie in
			if cookie.Expires.Before(latestSSOCookie.Expires) {
				cookies[i] = latestSSOCookie
			}
			break
		}
	}

	if !gerritSSOCookieExists {
		cookies = append(cookies, latestSSOCookie)
	}

	jiriCookieData, err := MarshalNSCookieData(cookies)
	if err != nil {
		return err
	}

	tempFile, err := ioutil.TempFile(path.Dir(jiriCookiePath), ".jiricookie*")
	if err != nil {
		return err
	}
	_, err = tempFile.Write(jiriCookieData)
	if err != nil {
		tempFile.Close()
		return err
	}
	tempFile.Close()
	if err := os.Rename(tempFile.Name(), jiriCookiePath); err != nil {
		os.Remove(tempFile.Name())
		return err
	}
	return nil
}

func loginRequired(cookie *http.Cookie) bool {
	// The correct way to determine cookie expiration time
	// is to use protobuf to unmarshal ticket data in cookie
	// However, we don't want to expose ticket data structure here,
	// So we use a work around
	cookie.Expires = cookie.Expires.Add(-ssoCookieAge).Add(ssoCookieLife)
	if cookie.Expires.Before(time.Now()) {
		return true
	}
	return false
}

func getCookiePath(jirix *jiri.X) (string, error) {
	if cookieFilePath, err := gitutil.New(jirix).ConfigGetKey("http.cookiefile"); err == nil {
		cookieFilePath = strings.TrimSpace(cookieFilePath)
		if _, err := os.Stat(cookieFilePath); err != nil {
			if os.IsNotExist(err) {
				return "", ErrCookieNotExist
			}
			return "", err
		}
		return cookieFilePath, nil
	}
	// http.cookiefile does not exist. Raise error to ask user to refresh git cookies
	return "", ErrCookieNotExist
}

func getSSOCookiePath() (string, error) {
	if ssoCookiePath == "" {
		return "", ErrSSOPathNotSet
	}

	if _, err := os.Stat(ssoCookiePath); err != nil {
		if os.IsNotExist(err) {
			return "", ErrCookieNotExist
		}
		return "", err
	}
	return ssoCookiePath, nil
}

func readMasterSSOCookie(path string) (*http.Cookie, error) {
	data, err := ioutil.ReadFile(path)
	if err != nil {
		return nil, err
	}

	lines := strings.SplitN(string(data), "\n", 2)
	cookie := http.Cookie{}

	for _, field := range strings.Split(lines[0], ",") {
		kv := strings.SplitN(field, "=", 2)
		switch kv[0] {
		case "domain":
			cookie.Domain = kv[1]
		case "name":
			cookie.Name = kv[1]
		case "path":
			cookie.Path = kv[1]
		case "value":
			cookie.Value = kv[1]
		case "expires":
			expires, err := strconv.ParseInt(kv[1], 10, 64)
			if err != nil {
				return nil, fmt.Errorf("invalid expires time in cookie: %v", err)
			}
			cookie.Expires = time.Unix(int64(expires), 0)
			cookie.RawExpires = kv[1]
		case "secure":
			if kv[1] != "True" {
				return nil, fmt.Errorf("secure value in cookie is not True")
			}
			cookie.Secure = true
		}
	}
	return &cookie, nil
}
