// 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"
	"net/http"
	"net/http/cookiejar"
	"net/url"
	"os"
	"path"
	"strconv"
	"strings"
	"sync"
	"time"

	"go.fuchsia.dev/jiri"
	"go.fuchsia.dev/jiri/gitutil"
	"go.fuchsia.dev/jiri/retry"
	"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(jirix *jiri.X, gerritHost, path string) ([]byte, error) {
	client := &http.Client{
		CheckRedirect: func(req *http.Request, via []*http.Request) error {
			return http.ErrUseLastResponse
		},
	}
	downloadPath := gerritHost + path
	// Retry the fetch a hardcoded number of times. jirix.Attempts is intended
	// to only apply to Git operations, and Git operation retries may be
	// disabled even when HTTP file fetches should still be retried.
	const maxAttempts = 3
	var b []byte
	err := retry.Function(jirix, func() error {
		resp, err := client.Get(downloadPath)
		if err != nil {
			return err
		}
		defer resp.Body.Close()
		// Check if there is an redirection
		if resp.StatusCode != http.StatusOK {
			if _, err := resp.Location(); err == nil {
				return ErrRedirectOnGerrit
			}
			return fmt.Errorf("expecting status code %d from %q, got %d ", http.StatusOK, downloadPath, resp.StatusCode)
		}
		b, err = io.ReadAll(resp.Body)
		return err
	}, fmt.Sprintf("Download %s", downloadPath), retry.AttemptsOpt(maxAttempts))
	return b, err
}

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 io.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 := os.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 := os.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 := os.CreateTemp(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 := os.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
}
