// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: MPL-2.0

package getproviders

import (
	"context"
	"encoding/json"
	"fmt"
	"log"
	"net/http"
	"net/http/httptest"
	"os"
	"strings"
	"testing"
	"time"

	"github.com/apparentlymart/go-versions/versions"
	"github.com/google/go-cmp/cmp"
	svchost "github.com/hashicorp/terraform-svchost"
	disco "github.com/hashicorp/terraform-svchost/disco"
	"github.com/hashicorp/terraform/internal/addrs"
)

func TestConfigureDiscoveryRetry(t *testing.T) {
	t.Run("default retry", func(t *testing.T) {
		if discoveryRetry != defaultRetry {
			t.Fatalf("expected retry %q, got %q", defaultRetry, discoveryRetry)
		}

		rc := newRegistryClient(nil, nil)
		if rc.httpClient.RetryMax != defaultRetry {
			t.Fatalf("expected client retry %q, got %q",
				defaultRetry, rc.httpClient.RetryMax)
		}
	})

	t.Run("configured retry", func(t *testing.T) {
		defer func(retryEnv string) {
			os.Setenv(registryDiscoveryRetryEnvName, retryEnv)
			discoveryRetry = defaultRetry
		}(os.Getenv(registryDiscoveryRetryEnvName))
		os.Setenv(registryDiscoveryRetryEnvName, "2")

		configureDiscoveryRetry()
		expected := 2
		if discoveryRetry != expected {
			t.Fatalf("expected retry %q, got %q",
				expected, discoveryRetry)
		}

		rc := newRegistryClient(nil, nil)
		if rc.httpClient.RetryMax != expected {
			t.Fatalf("expected client retry %q, got %q",
				expected, rc.httpClient.RetryMax)
		}
	})
}

func TestConfigureRegistryClientTimeout(t *testing.T) {
	t.Run("default timeout", func(t *testing.T) {
		if requestTimeout != defaultRequestTimeout {
			t.Fatalf("expected timeout %q, got %q",
				defaultRequestTimeout.String(), requestTimeout.String())
		}

		rc := newRegistryClient(nil, nil)
		if rc.httpClient.HTTPClient.Timeout != defaultRequestTimeout {
			t.Fatalf("expected client timeout %q, got %q",
				defaultRequestTimeout.String(), rc.httpClient.HTTPClient.Timeout.String())
		}
	})

	t.Run("configured timeout", func(t *testing.T) {
		defer func(timeoutEnv string) {
			os.Setenv(registryClientTimeoutEnvName, timeoutEnv)
			requestTimeout = defaultRequestTimeout
		}(os.Getenv(registryClientTimeoutEnvName))
		os.Setenv(registryClientTimeoutEnvName, "20")

		configureRequestTimeout()
		expected := 20 * time.Second
		if requestTimeout != expected {
			t.Fatalf("expected timeout %q, got %q",
				expected, requestTimeout.String())
		}

		rc := newRegistryClient(nil, nil)
		if rc.httpClient.HTTPClient.Timeout != expected {
			t.Fatalf("expected client timeout %q, got %q",
				expected, rc.httpClient.HTTPClient.Timeout.String())
		}
	})
}

// testRegistryServices starts up a local HTTP server running a fake provider registry
// service and returns a service discovery object pre-configured to consider
// the host "example.com" to be served by the fake registry service.
//
// The returned discovery object also knows the hostname "not.example.com"
// which does not have a provider registry at all and "too-new.example.com"
// which has a "providers.v99" service that is inoperable but could be useful
// to test the error reporting for detecting an unsupported protocol version.
// It also knows fails.example.com but it refers to an endpoint that doesn't
// correctly speak HTTP, to simulate a protocol error.
//
// The second return value is a function to call at the end of a test function
// to shut down the test server. After you call that function, the discovery
// object becomes useless.
func testRegistryServices(t *testing.T) (services *disco.Disco, baseURL string, cleanup func()) {
	server := httptest.NewServer(http.HandlerFunc(fakeRegistryHandler))

	services = disco.New()
	services.ForceHostServices(svchost.Hostname("example.com"), map[string]interface{}{
		"providers.v1": server.URL + "/providers/v1/",
	})
	services.ForceHostServices(svchost.Hostname("not.example.com"), map[string]interface{}{})
	services.ForceHostServices(svchost.Hostname("too-new.example.com"), map[string]interface{}{
		// This service doesn't actually work; it's here only to be
		// detected as "too new" by the discovery logic.
		"providers.v99": server.URL + "/providers/v99/",
	})
	services.ForceHostServices(svchost.Hostname("fails.example.com"), map[string]interface{}{
		"providers.v1": server.URL + "/fails-immediately/",
	})

	// We'll also permit registry.terraform.io here just because it's our
	// default and has some unique features that are not allowed on any other
	// hostname. It behaves the same as example.com, which should be preferred
	// if you're not testing something specific to the default registry in order
	// to ensure that most things are hostname-agnostic.
	services.ForceHostServices(svchost.Hostname("registry.terraform.io"), map[string]interface{}{
		"providers.v1": server.URL + "/providers/v1/",
	})

	return services, server.URL, func() {
		server.Close()
	}
}

// testRegistrySource is a wrapper around testServices that uses the created
// discovery object to produce a Source instance that is ready to use with the
// fake registry services.
//
// As with testServices, the second return value is a function to call at the end
// of your test in order to shut down the test server.
func testRegistrySource(t *testing.T) (source *RegistrySource, baseURL string, cleanup func()) {
	services, baseURL, close := testRegistryServices(t)
	source = NewRegistrySource(services)
	return source, baseURL, close
}

func fakeRegistryHandler(resp http.ResponseWriter, req *http.Request) {
	path := req.URL.EscapedPath()
	if strings.HasPrefix(path, "/fails-immediately/") {
		// Here we take over the socket and just close it immediately, to
		// simulate one possible way a server might not be an HTTP server.
		hijacker, ok := resp.(http.Hijacker)
		if !ok {
			// Not hijackable, so we'll just fail normally.
			// If this happens, tests relying on this will fail.
			resp.WriteHeader(500)
			resp.Write([]byte(`cannot hijack`))
			return
		}
		conn, _, err := hijacker.Hijack()
		if err != nil {
			resp.WriteHeader(500)
			resp.Write([]byte(`hijack failed`))
			return
		}
		conn.Close()
		return
	}

	if strings.HasPrefix(path, "/pkg/") {
		switch path {
		case "/pkg/awesomesauce/happycloud_1.2.0.zip":
			resp.Write([]byte("some zip file"))
		case "/pkg/awesomesauce/happycloud_1.2.0_SHA256SUMS":
			resp.Write([]byte("000000000000000000000000000000000000000000000000000000000000f00d happycloud_1.2.0.zip\n000000000000000000000000000000000000000000000000000000000000face happycloud_1.2.0_face.zip\n"))
		case "/pkg/awesomesauce/happycloud_1.2.0_SHA256SUMS.sig":
			resp.Write([]byte("GPG signature"))
		default:
			resp.WriteHeader(404)
			resp.Write([]byte("unknown package file download"))
		}
		return
	}

	if !strings.HasPrefix(path, "/providers/v1/") {
		resp.WriteHeader(404)
		resp.Write([]byte(`not a provider registry endpoint`))
		return
	}

	pathParts := strings.Split(path, "/")[3:]
	if len(pathParts) < 3 {
		resp.WriteHeader(404)
		resp.Write([]byte(`unexpected number of path parts`))
		return
	}
	log.Printf("[TRACE] fake provider registry request for %#v", pathParts)

	if pathParts[2] == "versions" {
		if len(pathParts) != 3 {
			resp.WriteHeader(404)
			resp.Write([]byte(`extraneous path parts`))
			return
		}

		switch pathParts[0] + "/" + pathParts[1] {
		case "awesomesauce/happycloud":
			resp.Header().Set("Content-Type", "application/json")
			resp.WriteHeader(200)
			// Note that these version numbers are intentionally misordered
			// so we can test that the client-side code places them in the
			// correct order (lowest precedence first).
			resp.Write([]byte(`{"versions":[{"version":"0.1.0","protocols":["1.0"]},{"version":"2.0.0","protocols":["99.0"]},{"version":"1.2.0","protocols":["5.0"]}, {"version":"1.0.0","protocols":["5.0"]}]}`))
		case "weaksauce/unsupported-protocol":
			resp.Header().Set("Content-Type", "application/json")
			resp.WriteHeader(200)
			resp.Write([]byte(`{"versions":[{"version":"1.0.0","protocols":["0.1"]}]}`))
		case "weaksauce/protocol-six":
			resp.Header().Set("Content-Type", "application/json")
			resp.WriteHeader(200)
			resp.Write([]byte(`{"versions":[{"version":"1.0.0","protocols":["6.0"]}]}`))
		case "weaksauce/no-versions":
			resp.Header().Set("Content-Type", "application/json")
			resp.WriteHeader(200)
			resp.Write([]byte(`{"versions":[],"warnings":["this provider is weaksauce"]}`))
		case "-/legacy":
			resp.Header().Set("Content-Type", "application/json")
			resp.WriteHeader(200)
			// This response is used for testing LookupLegacyProvider
			resp.Write([]byte(`{"id":"legacycorp/legacy"}`))
		case "-/moved":
			resp.Header().Set("Content-Type", "application/json")
			resp.WriteHeader(200)
			// This response is used for testing LookupLegacyProvider
			resp.Write([]byte(`{"id":"hashicorp/moved","moved_to":"acme/moved"}`))
		case "-/changetype":
			resp.Header().Set("Content-Type", "application/json")
			resp.WriteHeader(200)
			// This (unrealistic) response is used for error handling code coverage
			resp.Write([]byte(`{"id":"legacycorp/newtype"}`))
		case "-/invalid":
			resp.Header().Set("Content-Type", "application/json")
			resp.WriteHeader(200)
			// This (unrealistic) response is used for error handling code coverage
			resp.Write([]byte(`{"id":"some/invalid/id/string"}`))
		default:
			resp.WriteHeader(404)
			resp.Write([]byte(`unknown namespace or provider type`))
		}
		return
	}

	if len(pathParts) == 6 && pathParts[3] == "download" {
		switch pathParts[0] + "/" + pathParts[1] {
		case "awesomesauce/happycloud":
			if pathParts[4] == "nonexist" {
				resp.WriteHeader(404)
				resp.Write([]byte(`unsupported OS`))
				return
			}
			var protocols []string
			version := pathParts[2]
			switch version {
			case "0.1.0":
				protocols = []string{"1.0"}
			case "2.0.0":
				protocols = []string{"99.0"}
			default:
				protocols = []string{"5.0"}
			}

			body := map[string]interface{}{
				"protocols":             protocols,
				"os":                    pathParts[4],
				"arch":                  pathParts[5],
				"filename":              "happycloud_" + version + ".zip",
				"shasum":                "000000000000000000000000000000000000000000000000000000000000f00d",
				"download_url":          "/pkg/awesomesauce/happycloud_" + version + ".zip",
				"shasums_url":           "/pkg/awesomesauce/happycloud_" + version + "_SHA256SUMS",
				"shasums_signature_url": "/pkg/awesomesauce/happycloud_" + version + "_SHA256SUMS.sig",
				"signing_keys": map[string]interface{}{
					"gpg_public_keys": []map[string]interface{}{
						{
							"ascii_armor": HashicorpPublicKey,
						},
					},
				},
			}
			enc, err := json.Marshal(body)
			if err != nil {
				resp.WriteHeader(500)
				resp.Write([]byte("failed to encode body"))
			}
			resp.Header().Set("Content-Type", "application/json")
			resp.WriteHeader(200)
			resp.Write(enc)
		default:
			resp.WriteHeader(404)
			resp.Write([]byte(`unknown namespace/provider/version/architecture`))
		}
		return
	}

	resp.WriteHeader(404)
	resp.Write([]byte(`unrecognized path scheme`))
}

func TestProviderVersions(t *testing.T) {
	source, _, close := testRegistrySource(t)
	defer close()

	tests := []struct {
		provider     addrs.Provider
		wantVersions map[string][]string
		wantErr      string
	}{
		{
			addrs.MustParseProviderSourceString("example.com/awesomesauce/happycloud"),
			map[string][]string{
				"0.1.0": {"1.0"},
				"1.0.0": {"5.0"},
				"1.2.0": {"5.0"},
				"2.0.0": {"99.0"},
			},
			``,
		},
		{
			addrs.MustParseProviderSourceString("example.com/weaksauce/no-versions"),
			nil,
			``,
		},
		{
			addrs.MustParseProviderSourceString("example.com/nonexist/nonexist"),
			nil,
			`provider registry example.com does not have a provider named example.com/nonexist/nonexist`,
		},
	}
	for _, test := range tests {
		t.Run(test.provider.String(), func(t *testing.T) {
			client, err := source.registryClient(test.provider.Hostname)
			if err != nil {
				t.Fatal(err)
			}

			gotVersions, _, err := client.ProviderVersions(context.Background(), test.provider)

			if err != nil {
				if test.wantErr == "" {
					t.Fatalf("wrong error\ngot:  %s\nwant: <nil>", err.Error())
				}
				if got, want := err.Error(), test.wantErr; got != want {
					t.Fatalf("wrong error\ngot:  %s\nwant: %s", got, want)
				}
				return
			}

			if test.wantErr != "" {
				t.Fatalf("wrong error\ngot:  <nil>\nwant: %s", test.wantErr)
			}

			if diff := cmp.Diff(test.wantVersions, gotVersions); diff != "" {
				t.Errorf("wrong result\n%s", diff)
			}
		})
	}
}

func TestFindClosestProtocolCompatibleVersion(t *testing.T) {
	source, _, close := testRegistrySource(t)
	defer close()

	tests := map[string]struct {
		provider       addrs.Provider
		version        Version
		wantSuggestion Version
		wantErr        string
	}{
		"pinned version too old": {
			addrs.MustParseProviderSourceString("example.com/awesomesauce/happycloud"),
			MustParseVersion("0.1.0"),
			MustParseVersion("1.2.0"),
			``,
		},
		"pinned version too new": {
			addrs.MustParseProviderSourceString("example.com/awesomesauce/happycloud"),
			MustParseVersion("2.0.0"),
			MustParseVersion("1.2.0"),
			``,
		},
		// This should not actually happen, the function is only meant to be
		// called when the requested provider version is not supported
		"pinned version just right": {
			addrs.MustParseProviderSourceString("example.com/awesomesauce/happycloud"),
			MustParseVersion("1.2.0"),
			MustParseVersion("1.2.0"),
			``,
		},
		"nonexisting provider": {
			addrs.MustParseProviderSourceString("example.com/nonexist/nonexist"),
			MustParseVersion("1.2.0"),
			versions.Unspecified,
			`provider registry example.com does not have a provider named example.com/nonexist/nonexist`,
		},
		"versionless provider": {
			addrs.MustParseProviderSourceString("example.com/weaksauce/no-versions"),
			MustParseVersion("1.2.0"),
			versions.Unspecified,
			``,
		},
		"unsupported provider protocol": {
			addrs.MustParseProviderSourceString("example.com/weaksauce/unsupported-protocol"),
			MustParseVersion("1.0.0"),
			versions.Unspecified,
			``,
		},
		"provider protocol six": {
			addrs.MustParseProviderSourceString("example.com/weaksauce/protocol-six"),
			MustParseVersion("1.0.0"),
			MustParseVersion("1.0.0"),
			``,
		},
	}
	for name, test := range tests {
		t.Run(name, func(t *testing.T) {
			client, err := source.registryClient(test.provider.Hostname)
			if err != nil {
				t.Fatal(err)
			}

			got, err := client.findClosestProtocolCompatibleVersion(context.Background(), test.provider, test.version)

			if err != nil {
				if test.wantErr == "" {
					t.Fatalf("wrong error\ngot:  %s\nwant: <nil>", err.Error())
				}
				if got, want := err.Error(), test.wantErr; got != want {
					t.Fatalf("wrong error\ngot:  %s\nwant: %s", got, want)
				}
				return
			}

			if test.wantErr != "" {
				t.Fatalf("wrong error\ngot:  <nil>\nwant: %s", test.wantErr)
			}

			fmt.Printf("Got: %s, Want: %s\n", got, test.wantSuggestion)

			if !got.Same(test.wantSuggestion) {
				t.Fatalf("wrong result\ngot:  %s\nwant: %s", got.String(), test.wantSuggestion.String())
			}
		})
	}
}
