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

// authtest is a diagnostic tool for implementations of the GOAUTH protocol
// described in https://golang.org/issue/26232.
//
// It accepts a single URL as an argument, and executes the GOAUTH protocol to
// fetch and display the headers for that URL.
//
// CAUTION: authtest logs the GOAUTH responses, which may include user
// credentials, to stderr. Do not post its output unless you are certain that
// all of the credentials involved are fake!
package main

import (
	"bufio"
	"bytes"
	"flag"
	"fmt"
	"io"
	"log"
	"net/http"
	"net/textproto"
	"net/url"
	"os"
	"os/exec"
	"path/filepath"
	"strings"
)

var v = flag.Bool("v", false, "if true, log GOAUTH responses to stderr")

func main() {
	log.SetFlags(log.LstdFlags | log.Lshortfile)
	flag.Parse()
	args := flag.Args()
	if len(args) != 1 {
		log.Fatalf("usage: [GOAUTH=CMD...] %s URL", filepath.Base(os.Args[0]))
	}

	resp := try(args[0], nil)
	if resp.StatusCode == http.StatusOK {
		return
	}

	resp = try(args[0], resp)
	if resp.StatusCode != http.StatusOK {
		os.Exit(1)
	}
}

func try(url string, prev *http.Response) *http.Response {
	req := new(http.Request)
	if prev != nil {
		*req = *prev.Request
	} else {
		var err error
		req, err = http.NewRequest("HEAD", os.Args[1], nil)
		if err != nil {
			log.Fatal(err)
		}
	}

goauth:
	for _, argList := range strings.Split(os.Getenv("GOAUTH"), ";") {
		// TODO(golang.org/issue/26849): If we escape quoted strings in GOFLAGS, use
		// the same quoting here.
		args := strings.Split(argList, " ")
		if len(args) == 0 || args[0] == "" {
			log.Fatalf("invalid or empty command in GOAUTH")
		}

		creds, err := getCreds(args, prev)
		if err != nil {
			log.Fatal(err)
		}
		for _, c := range creds {
			if c.Apply(req) {
				fmt.Fprintf(os.Stderr, "# request to %s\n", req.URL)
				fmt.Fprintf(os.Stderr, "%s %s %s\n", req.Method, req.URL, req.Proto)
				req.Header.Write(os.Stderr)
				fmt.Fprintln(os.Stderr)
				break goauth
			}
		}
	}

	resp, err := http.DefaultClient.Do(req)
	if err != nil {
		log.Fatal(err)
	}
	defer resp.Body.Close()

	if resp.StatusCode != http.StatusOK && resp.StatusCode < 400 || resp.StatusCode > 500 {
		log.Fatalf("unexpected status: %v", resp.Status)
	}

	fmt.Fprintf(os.Stderr, "# response from %s\n", resp.Request.URL)
	formatHead(os.Stderr, resp)
	return resp
}

func formatHead(out io.Writer, resp *http.Response) {
	fmt.Fprintf(out, "%s %s\n", resp.Proto, resp.Status)
	if err := resp.Header.Write(out); err != nil {
		log.Fatal(err)
	}
	fmt.Fprintln(out)
}

type Cred struct {
	URLPrefixes []*url.URL
	Header      http.Header
}

func (c Cred) Apply(req *http.Request) bool {
	if req.URL == nil {
		return false
	}
	ok := false
	for _, prefix := range c.URLPrefixes {
		if prefix.Host == req.URL.Host &&
			(req.URL.Path == prefix.Path ||
				(strings.HasPrefix(req.URL.Path, prefix.Path) &&
					(strings.HasSuffix(prefix.Path, "/") ||
						req.URL.Path[len(prefix.Path)] == '/'))) {
			ok = true
			break
		}
	}
	if !ok {
		return false
	}

	for k, vs := range c.Header {
		req.Header.Del(k)
		for _, v := range vs {
			req.Header.Add(k, v)
		}
	}
	return true
}

func (c Cred) String() string {
	var buf strings.Builder
	for _, u := range c.URLPrefixes {
		fmt.Fprintln(&buf, u)
	}
	buf.WriteString("\n")
	c.Header.Write(&buf)
	buf.WriteString("\n")
	return buf.String()
}

func getCreds(args []string, resp *http.Response) ([]Cred, error) {
	cmd := exec.Command(args[0], args[1:]...)
	cmd.Stderr = os.Stderr

	if resp != nil {
		u := *resp.Request.URL
		u.RawQuery = ""
		cmd.Args = append(cmd.Args, u.String())
	}

	var head strings.Builder
	if resp != nil {
		formatHead(&head, resp)
	}
	cmd.Stdin = strings.NewReader(head.String())

	fmt.Fprintf(os.Stderr, "# %s\n", strings.Join(cmd.Args, " "))
	out, err := cmd.Output()
	if err != nil {
		return nil, fmt.Errorf("%s: %v", strings.Join(cmd.Args, " "), err)
	}
	os.Stderr.Write(out)
	os.Stderr.WriteString("\n")

	var creds []Cred
	r := textproto.NewReader(bufio.NewReader(bytes.NewReader(out)))
	line := 0
readLoop:
	for {
		var prefixes []*url.URL
		for {
			prefix, err := r.ReadLine()
			if err == io.EOF {
				if len(prefixes) > 0 {
					return nil, fmt.Errorf("line %d: %v", line, io.ErrUnexpectedEOF)
				}
				break readLoop
			}
			line++

			if prefix == "" {
				if len(prefixes) == 0 {
					return nil, fmt.Errorf("line %d: unexpected newline", line)
				}
				break
			}
			u, err := url.Parse(prefix)
			if err != nil {
				return nil, fmt.Errorf("line %d: malformed URL: %v", line, err)
			}
			if u.Scheme != "https" {
				return nil, fmt.Errorf("line %d: non-HTTPS URL %q", line, prefix)
			}
			if len(u.RawQuery) > 0 {
				return nil, fmt.Errorf("line %d: unexpected query string in URL %q", line, prefix)
			}
			if len(u.Fragment) > 0 {
				return nil, fmt.Errorf("line %d: unexpected fragment in URL %q", line, prefix)
			}
			prefixes = append(prefixes, u)
		}

		header, err := r.ReadMIMEHeader()
		if err != nil {
			return nil, fmt.Errorf("headers at line %d: %v", line, err)
		}
		if len(header) > 0 {
			creds = append(creds, Cred{
				URLPrefixes: prefixes,
				Header:      http.Header(header),
			})
		}
	}

	return creds, nil
}
