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

package getproviders

import (
	"context"
	"encoding/json"
	"errors"
	"fmt"
	"net/http"
	"net/url"
	"path"

	"github.com/hashicorp/go-retryablehttp"
	svchost "github.com/hashicorp/terraform-svchost"
	"github.com/hashicorp/terraform/internal/addrs"
)

// MissingProviderSuggestion takes a provider address that failed installation
// due to the remote registry reporting that it didn't exist, and attempts
// to find another provider that the user might have meant to select.
//
// If the result is equal to the given address then that indicates that there
// is no suggested alternative to offer, either because the function
// successfully determined there is no recorded alternative or because the
// lookup failed somehow. We don't consider a failure to find a suggestion
// as an installation failure, because the caller should already be reporting
// that the provider didn't exist anyway and this is only extra context for
// that error message.
//
// The result of this is a best effort, so any UI presenting it should be
// careful to give it only as a possibility and not necessarily a suitable
// replacement for the given provider.
//
// In practice today this function only knows how to suggest alternatives for
// "default" providers, which is to say ones that are in the hashicorp
// namespace in the Terraform registry. It will always return no result for
// any other provider. That might change in future if we introduce other ways
// to discover provider suggestions.
//
// If the given context is cancelled then this function might not return a
// renaming suggestion even if one would've been available for a completed
// request.
func MissingProviderSuggestion(ctx context.Context, addr addrs.Provider, source Source, reqs Requirements) addrs.Provider {
	if !addrs.IsDefaultProvider(addr) {
		return addr
	}

	// Before possibly looking up legacy naming, see if the user has another provider
	// named in their requirements that is of the same type, and offer that
	// as a suggestion
	for req := range reqs {
		if req != addr && req.Type == addr.Type {
			return req
		}
	}

	// Our strategy here, for a default provider, is to use the default
	// registry's special API for looking up "legacy" providers and try looking
	// for a legacy provider whose type name matches the type of the given
	// provider. This should then find a suitable answer for any provider
	// that was originally auto-installable in v0.12 and earlier but moved
	// into a non-default namespace as part of introducing the hierarchical
	// provider namespace.
	//
	// To achieve that, we need to find the direct registry client in
	// particular from the given source, because that is the only Source
	// implementation that can actually handle a legacy provider lookup.
	regSource := findLegacyProviderLookupSource(addr.Hostname, source)
	if regSource == nil {
		// If there's no direct registry source in the installation config
		// then we can't provide a renaming suggestion.
		return addr
	}

	defaultNS, redirectNS, err := regSource.lookupLegacyProviderNamespace(ctx, addr.Hostname, addr.Type)
	if err != nil {
		return addr
	}

	switch {
	case redirectNS != "":
		return addrs.Provider{
			Hostname:  addr.Hostname,
			Namespace: redirectNS,
			Type:      addr.Type,
		}
	default:
		return addrs.Provider{
			Hostname:  addr.Hostname,
			Namespace: defaultNS,
			Type:      addr.Type,
		}
	}
}

// findLegacyProviderLookupSource tries to find a *RegistrySource that can talk
// to the given registry host in the given Source. It might be given directly,
// or it might be given indirectly via a MultiSource where the selector
// includes a wildcard for registry.terraform.io.
//
// Returns nil if the given source does not have any configured way to talk
// directly to the given host.
//
// If the given source contains multiple sources that can talk to the given
// host directly, the first one in the sequence takes preference. In practice
// it's pointless to have two direct installation sources that match the same
// hostname anyway, so this shouldn't arise in normal use.
func findLegacyProviderLookupSource(host svchost.Hostname, source Source) *RegistrySource {
	switch source := source.(type) {

	case *RegistrySource:
		// Easy case: the source is a registry source directly, and so we'll
		// just use it.
		return source

	case *MemoizeSource:
		// Also easy: the source is a memoize wrapper, so defer to its
		// underlying source.
		return findLegacyProviderLookupSource(host, source.underlying)

	case MultiSource:
		// Trickier case: if it's a multisource then we need to scan over
		// its selectors until we find one that is a *RegistrySource _and_
		// that is configured to accept arbitrary providers from the
		// given hostname.

		// For our matching purposes we'll use an address that would not be
		// valid as a real provider FQN and thus can only match a selector
		// that has no filters at all or a selector that wildcards everything
		// except the hostname, like "registry.terraform.io/*/*"
		matchAddr := addrs.Provider{
			Hostname: host,
			// Other fields are intentionally left empty, to make this invalid
			// as a specific provider address.
		}

		for _, selector := range source {
			// If this source has suitable matching patterns to install from
			// the given hostname then we'll recursively search inside it
			// for *RegistrySource objects.
			if selector.CanHandleProvider(matchAddr) {
				ret := findLegacyProviderLookupSource(host, selector.Source)
				if ret != nil {
					return ret
				}
			}
		}

		// If we get here then there were no selectors that are both configured
		// to handle modules from the given hostname and that are registry
		// sources, so we fail.
		return nil

	default:
		// This source cannot be and cannot contain a *RegistrySource, so
		// we fail.
		return nil
	}
}

// lookupLegacyProviderNamespace is a special method available only on
// RegistrySource which can deal with legacy provider addresses that contain
// only a type and leave the namespace implied.
//
// It asks the registry at the given hostname to provide a default namespace
// for the given provider type, which can be combined with the given hostname
// and type name to produce a fully-qualified provider address.
//
// Not all unqualified type names can be resolved to a default namespace. If
// the request fails, this method returns an error describing the failure.
//
// This method exists only to allow compatibility with unqualified names
// in older configurations. New configurations should be written so as not to
// depend on it, and this fallback mechanism will likely be removed altogether
// in a future Terraform version.
func (s *RegistrySource) lookupLegacyProviderNamespace(ctx context.Context, hostname svchost.Hostname, typeName string) (string, string, error) {
	client, err := s.registryClient(hostname)
	if err != nil {
		return "", "", err
	}
	return client.legacyProviderDefaultNamespace(ctx, typeName)
}

// legacyProviderDefaultNamespace returns the raw address strings produced by
// the registry when asked about the given unqualified provider type name.
// The returned namespace string is taken verbatim from the registry's response.
//
// This method exists only to allow compatibility with unqualified names
// in older configurations. New configurations should be written so as not to
// depend on it.
func (c *registryClient) legacyProviderDefaultNamespace(ctx context.Context, typeName string) (string, string, error) {
	endpointPath, err := url.Parse(path.Join("-", typeName, "versions"))
	if err != nil {
		// Should never happen because we're constructing this from
		// already-validated components.
		return "", "", err
	}
	endpointURL := c.baseURL.ResolveReference(endpointPath)

	req, err := retryablehttp.NewRequest("GET", endpointURL.String(), nil)
	if err != nil {
		return "", "", err
	}
	req = req.WithContext(ctx)
	c.addHeadersToRequest(req.Request)

	// This is just to give us something to return in error messages. It's
	// not a proper provider address.
	placeholderProviderAddr := addrs.NewLegacyProvider(typeName)

	resp, err := c.httpClient.Do(req)
	if err != nil {
		return "", "", c.errQueryFailed(placeholderProviderAddr, err)
	}
	defer resp.Body.Close()

	switch resp.StatusCode {
	case http.StatusOK:
		// Great!
	case http.StatusNotFound:
		return "", "", ErrProviderNotFound{
			Provider: placeholderProviderAddr,
		}
	case http.StatusUnauthorized, http.StatusForbidden:
		return "", "", c.errUnauthorized(placeholderProviderAddr.Hostname)
	default:
		return "", "", c.errQueryFailed(placeholderProviderAddr, errors.New(resp.Status))
	}

	type ResponseBody struct {
		Id      string `json:"id"`
		MovedTo string `json:"moved_to"`
	}
	var body ResponseBody

	dec := json.NewDecoder(resp.Body)
	if err := dec.Decode(&body); err != nil {
		return "", "", c.errQueryFailed(placeholderProviderAddr, err)
	}

	provider, diags := addrs.ParseProviderSourceString(body.Id)
	if diags.HasErrors() {
		return "", "", fmt.Errorf("Error parsing provider ID from Registry: %s", diags.Err())
	}

	if provider.Type != typeName {
		return "", "", fmt.Errorf("Registry returned provider with type %q, expected %q", provider.Type, typeName)
	}

	var movedTo addrs.Provider
	if body.MovedTo != "" {
		movedTo, diags = addrs.ParseProviderSourceString(body.MovedTo)
		if diags.HasErrors() {
			return "", "", fmt.Errorf("Error parsing provider ID from Registry: %s", diags.Err())
		}

		if movedTo.Type != typeName {
			return "", "", fmt.Errorf("Registry returned provider with type %q, expected %q", movedTo.Type, typeName)
		}
	}

	return provider.Namespace, movedTo.Namespace, nil
}
