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

package auth

import (
	"cmd/internal/quoted"
	"fmt"
	"maps"
	"net/http"
	"net/url"
	"os/exec"
	"strings"
)

// runAuthCommand executes a user provided GOAUTH command, parses its output, and
// returns a mapping of prefix → http.Header.
// It uses the client to verify the credential and passes the status to the
// command's stdin.
// res is used for the GOAUTH command's stdin.
func runAuthCommand(command string, url string, res *http.Response) (map[string]http.Header, error) {
	if command == "" {
		panic("GOAUTH invoked an empty authenticator command:" + command) // This should be caught earlier.
	}
	cmd, err := buildCommand(command)
	if err != nil {
		return nil, err
	}
	if url != "" {
		cmd.Args = append(cmd.Args, url)
	}
	cmd.Stderr = new(strings.Builder)
	if res != nil && writeResponseToStdin(cmd, res) != nil {
		return nil, fmt.Errorf("could not run command %s: %v\n%s", command, err, cmd.Stderr)
	}
	out, err := cmd.Output()
	if err != nil {
		return nil, fmt.Errorf("could not run command %s: %v\n%s", command, err, cmd.Stderr)
	}
	credentials, err := parseUserAuth(string(out))
	if err != nil {
		return nil, fmt.Errorf("cannot parse output of GOAUTH command %s: %v", command, err)
	}
	return credentials, nil
}

// parseUserAuth parses the output from a GOAUTH command and
// returns a mapping of prefix → http.Header without the leading "https://"
// or an error if the data does not follow the expected format.
// Returns a nil error and an empty map if the data is empty.
// See the expected format in 'go help goauth'.
func parseUserAuth(data string) (map[string]http.Header, error) {
	credentials := make(map[string]http.Header)
	for data != "" {
		var line string
		var ok bool
		var urls []string
		// Parse URLS first.
		for {
			line, data, ok = strings.Cut(data, "\n")
			if !ok {
				return nil, fmt.Errorf("invalid format: missing empty line after URLs")
			}
			if line == "" {
				break
			}
			u, err := url.ParseRequestURI(line)
			if err != nil {
				return nil, fmt.Errorf("could not parse URL %s: %v", line, err)
			}
			urls = append(urls, u.String())
		}
		// Parse Headers second.
		header := make(http.Header)
		for {
			line, data, ok = strings.Cut(data, "\n")
			if !ok {
				return nil, fmt.Errorf("invalid format: missing empty line after headers")
			}
			if line == "" {
				break
			}
			name, value, ok := strings.Cut(line, ": ")
			value = strings.TrimSpace(value)
			if !ok || !validHeaderFieldName(name) || !validHeaderFieldValue(value) {
				return nil, fmt.Errorf("invalid format: invalid header line")
			}
			header.Add(name, value)
		}
		maps.Copy(credentials, mapHeadersToPrefixes(urls, header))
	}
	return credentials, nil
}

// mapHeadersToPrefixes returns a mapping of prefix → http.Header without
// the leading "https://".
func mapHeadersToPrefixes(prefixes []string, header http.Header) map[string]http.Header {
	prefixToHeaders := make(map[string]http.Header, len(prefixes))
	for _, p := range prefixes {
		p = strings.TrimPrefix(p, "https://")
		prefixToHeaders[p] = header.Clone() // Clone the header to avoid sharing
	}
	return prefixToHeaders
}

func buildCommand(command string) (*exec.Cmd, error) {
	words, err := quoted.Split(command)
	if err != nil {
		return nil, fmt.Errorf("cannot parse GOAUTH command %s: %v", command, err)
	}
	cmd := exec.Command(words[0], words[1:]...)
	return cmd, nil
}

// writeResponseToStdin writes the HTTP response to the command's stdin.
func writeResponseToStdin(cmd *exec.Cmd, res *http.Response) error {
	var output strings.Builder
	output.WriteString(res.Proto + " " + res.Status + "\n")
	for k, v := range res.Header {
		output.WriteString(k + ": " + strings.Join(v, ", ") + "\n")
	}
	output.WriteString("\n")
	cmd.Stdin = strings.NewReader(output.String())
	return nil
}
