// Copyright 2023 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 cgi

import (
	"fmt"
	"io"
	"net/http"
	"os"
	"path"
	"sort"
	"strings"
	"time"
)

func cgiMain() {
	switch path.Join(os.Getenv("SCRIPT_NAME"), os.Getenv("PATH_INFO")) {
	case "/bar", "/test.cgi", "/myscript/bar", "/test.cgi/extrapath":
		testCGI()
		return
	}
	childCGIProcess()
}

// testCGI is a CGI program translated from a Perl program to complete host_test.
// test cases in host_test should be provided by testCGI.
func testCGI() {
	req, err := Request()
	if err != nil {
		panic(err)
	}

	err = req.ParseForm()
	if err != nil {
		panic(err)
	}

	params := req.Form
	if params.Get("loc") != "" {
		fmt.Printf("Location: %s\r\n\r\n", params.Get("loc"))
		return
	}

	fmt.Printf("Content-Type: text/html\r\n")
	fmt.Printf("X-CGI-Pid: %d\r\n", os.Getpid())
	fmt.Printf("X-Test-Header: X-Test-Value\r\n")
	fmt.Printf("\r\n")

	if params.Get("writestderr") != "" {
		fmt.Fprintf(os.Stderr, "Hello, stderr!\n")
	}

	if params.Get("bigresponse") != "" {
		// 17 MB, for OS X: golang.org/issue/4958
		line := strings.Repeat("A", 1024)
		for i := 0; i < 17*1024; i++ {
			fmt.Printf("%s\r\n", line)
		}
		return
	}

	fmt.Printf("test=Hello CGI\r\n")

	keys := make([]string, 0, len(params))
	for k := range params {
		keys = append(keys, k)
	}
	sort.Strings(keys)
	for _, key := range keys {
		fmt.Printf("param-%s=%s\r\n", key, params.Get(key))
	}

	envs := envMap(os.Environ())
	keys = make([]string, 0, len(envs))
	for k := range envs {
		keys = append(keys, k)
	}
	sort.Strings(keys)
	for _, key := range keys {
		fmt.Printf("env-%s=%s\r\n", key, envs[key])
	}

	cwd, _ := os.Getwd()
	fmt.Printf("cwd=%s\r\n", cwd)
}

type neverEnding byte

func (b neverEnding) Read(p []byte) (n int, err error) {
	for i := range p {
		p[i] = byte(b)
	}
	return len(p), nil
}

// childCGIProcess is used by integration_test to complete unit tests.
func childCGIProcess() {
	if os.Getenv("REQUEST_METHOD") == "" {
		// Not in a CGI environment; skipping test.
		return
	}
	switch os.Getenv("REQUEST_URI") {
	case "/immediate-disconnect":
		os.Exit(0)
	case "/no-content-type":
		fmt.Printf("Content-Length: 6\n\nHello\n")
		os.Exit(0)
	case "/empty-headers":
		fmt.Printf("\nHello")
		os.Exit(0)
	}
	Serve(http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) {
		if req.FormValue("nil-request-body") == "1" {
			fmt.Fprintf(rw, "nil-request-body=%v\n", req.Body == nil)
			return
		}
		rw.Header().Set("X-Test-Header", "X-Test-Value")
		req.ParseForm()
		if req.FormValue("no-body") == "1" {
			return
		}
		if eb, ok := req.Form["exact-body"]; ok {
			io.WriteString(rw, eb[0])
			return
		}
		if req.FormValue("write-forever") == "1" {
			io.Copy(rw, neverEnding('a'))
			for {
				time.Sleep(5 * time.Second) // hang forever, until killed
			}
		}
		fmt.Fprintf(rw, "test=Hello CGI-in-CGI\n")
		for k, vv := range req.Form {
			for _, v := range vv {
				fmt.Fprintf(rw, "param-%s=%s\n", k, v)
			}
		}
		for _, kv := range os.Environ() {
			fmt.Fprintf(rw, "env-%s\n", kv)
		}
	}))
	os.Exit(0)
}
