// Copyright 2019 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// cookieauth uses a “Netscape cookie file” to implement the GOAUTH protocol
// described in https://golang.org/issue/26232.
// It expects the location of the file as the first command-line argument.
//
// Example GOAUTH usage:
//
//	export GOAUTH="cookieauth $(git config --get http.cookieFile)"
//
// See http://www.cookiecentral.com/faq/#3.5 for a description of the Netscape
// cookie file format.
package main

import (
	"bufio"
	"fmt"
	"io"
	"log"
	"net/http"
	"net/http/cookiejar"
	"net/url"
	"os"
	"strconv"
	"strings"
	"time"
	"unicode"
)

func main() {
	if len(os.Args) < 2 {
		fmt.Fprintf(os.Stderr, "usage: %s COOKIEFILE [URL]\n", os.Args[0])
		os.Exit(2)
	}

	log.SetPrefix("cookieauth: ")

	f, err := os.Open(os.Args[1])
	if err != nil {
		log.Fatalf("failed to read cookie file: %v\n", os.Args[1])
		os.Exit(1)
	}
	defer f.Close()

	var (
		targetURL  *url.URL
		targetURLs = map[string]*url.URL{}
	)
	if len(os.Args) == 3 {
		targetURL, err = url.ParseRequestURI(os.Args[2])
		if err != nil {
			log.Fatalf("invalid request URI (%v): %q\n", err, os.Args[2])
		}
		targetURLs[targetURL.String()] = targetURL
	} else if len(os.Args) > 3 {
		// Extra arguments were passed: maybe the protocol was expanded?
		// We don't know how to interpret the request, so ignore it.
		return
	}

	entries, err := parseCookieFile(f.Name(), f)
	if err != nil {
		log.Fatalf("error reading cookie file: %v\n", f.Name())
	}

	jar, err := cookiejar.New(nil)
	if err != nil {
		log.Fatalf("failed to initialize cookie jar: %v\n", err)
	}

	for _, e := range entries {
		u := &url.URL{
			Scheme: "https",
			Host:   e.Host,
			Path:   e.Cookie.Path,
		}

		if targetURL == nil {
			targetURLs[u.String()] = u
		}

		jar.SetCookies(u, []*http.Cookie{&e.Cookie})
	}

	for _, u := range targetURLs {
		req := &http.Request{URL: u, Header: make(http.Header)}
		for _, c := range jar.Cookies(req.URL) {
			req.AddCookie(c)
		}
		fmt.Printf("%s\n\n", u)
		req.Header.Write(os.Stdout)
		fmt.Println()
	}
}

type Entry struct {
	Host   string
	Cookie http.Cookie
}

// parseCookieFile parses a Netscape cookie file as described in
// http://www.cookiecentral.com/faq/#3.5.
func parseCookieFile(name string, r io.Reader) ([]*Entry, error) {
	var entries []*Entry
	s := bufio.NewScanner(r)
	line := 0
	for s.Scan() {
		line++
		text := strings.TrimSpace(s.Text())
		if len(text) < 2 || (text[0] == '#' && unicode.IsSpace(rune(text[1]))) {
			continue
		}

		e, err := parseCookieLine(text)
		if err != nil {
			log.Printf("%s:%d: %v\n", name, line, err)
			continue
		}
		entries = append(entries, e)
	}
	return entries, s.Err()
}

func parseCookieLine(line string) (*Entry, error) {
	f := strings.Fields(line)
	if len(f) < 7 {
		return nil, fmt.Errorf("found %d columns; want 7", len(f))
	}

	e := new(Entry)
	c := &e.Cookie

	if domain := f[0]; strings.HasPrefix(domain, "#HttpOnly_") {
		c.HttpOnly = true
		e.Host = strings.TrimPrefix(domain[10:], ".")
	} else {
		e.Host = strings.TrimPrefix(domain, ".")
	}

	isDomain, err := strconv.ParseBool(f[1])
	if err != nil {
		return nil, fmt.Errorf("non-boolean domain flag: %v", err)
	}
	if isDomain {
		c.Domain = e.Host
	}

	c.Path = f[2]

	c.Secure, err = strconv.ParseBool(f[3])
	if err != nil {
		return nil, fmt.Errorf("non-boolean secure flag: %v", err)
	}

	expiration, err := strconv.ParseInt(f[4], 10, 64)
	if err != nil {
		return nil, fmt.Errorf("malformed expiration: %v", err)
	}
	c.Expires = time.Unix(expiration, 0)

	c.Name = f[5]
	c.Value = f[6]

	return e, nil
}
