package endpoints

import (
	"fmt"
	"regexp"

	"github.com/aws/aws-sdk-go/aws/awserr"
)

// Options provide the configuration needed to direct how the
// endpoints will be resolved.
type Options struct {
	// DisableSSL forces the endpoint to be resolved as HTTP.
	// instead of HTTPS if the service supports it.
	DisableSSL bool

	// Sets the resolver to resolve the endpoint as a dualstack endpoint
	// for the service. If dualstack support for a service is not known and
	// StrictMatching is not enabled a dualstack endpoint for the service will
	// be returned. This endpoint may not be valid. If StrictMatching is
	// enabled only services that are known to support dualstack will return
	// dualstack endpoints.
	UseDualStack bool

	// Enables strict matching of services and regions resolved endpoints.
	// If the partition doesn't enumerate the exact service and region an
	// error will be returned. This option will prevent returning endpoints
	// that look valid, but may not resolve to any real endpoint.
	StrictMatching bool

	// Enables resolving a service endpoint based on the region provided if the
	// service does not exist. The service endpoint ID will be used as the service
	// domain name prefix. By default the endpoint resolver requires the service
	// to be known when resolving endpoints.
	//
	// If resolving an endpoint on the partition list the provided region will
	// be used to determine which partition's domain name pattern to the service
	// endpoint ID with. If both the service and region are unknown and resolving
	// the endpoint on partition list an UnknownEndpointError error will be returned.
	//
	// If resolving and endpoint on a partition specific resolver that partition's
	// domain name pattern will be used with the service endpoint ID. If both
	// region and service do not exist when resolving an endpoint on a specific
	// partition the partition's domain pattern will be used to combine the
	// endpoint and region together.
	//
	// This option is ignored if StrictMatching is enabled.
	ResolveUnknownService bool
}

// Set combines all of the option functions together.
func (o *Options) Set(optFns ...func(*Options)) {
	for _, fn := range optFns {
		fn(o)
	}
}

// DisableSSLOption sets the DisableSSL options. Can be used as a functional
// option when resolving endpoints.
func DisableSSLOption(o *Options) {
	o.DisableSSL = true
}

// UseDualStackOption sets the UseDualStack option. Can be used as a functional
// option when resolving endpoints.
func UseDualStackOption(o *Options) {
	o.UseDualStack = true
}

// StrictMatchingOption sets the StrictMatching option. Can be used as a functional
// option when resolving endpoints.
func StrictMatchingOption(o *Options) {
	o.StrictMatching = true
}

// ResolveUnknownServiceOption sets the ResolveUnknownService option. Can be used
// as a functional option when resolving endpoints.
func ResolveUnknownServiceOption(o *Options) {
	o.ResolveUnknownService = true
}

// A Resolver provides the interface for functionality to resolve endpoints.
// The build in Partition and DefaultResolver return value satisfy this interface.
type Resolver interface {
	EndpointFor(service, region string, opts ...func(*Options)) (ResolvedEndpoint, error)
}

// ResolverFunc is a helper utility that wraps a function so it satisfies the
// Resolver interface. This is useful when you want to add additional endpoint
// resolving logic, or stub out specific endpoints with custom values.
type ResolverFunc func(service, region string, opts ...func(*Options)) (ResolvedEndpoint, error)

// EndpointFor wraps the ResolverFunc function to satisfy the Resolver interface.
func (fn ResolverFunc) EndpointFor(service, region string, opts ...func(*Options)) (ResolvedEndpoint, error) {
	return fn(service, region, opts...)
}

var schemeRE = regexp.MustCompile("^([^:]+)://")

// AddScheme adds the HTTP or HTTPS schemes to a endpoint URL if there is no
// scheme. If disableSSL is true HTTP will set HTTP instead of the default HTTPS.
//
// If disableSSL is set, it will only set the URL's scheme if the URL does not
// contain a scheme.
func AddScheme(endpoint string, disableSSL bool) string {
	if !schemeRE.MatchString(endpoint) {
		scheme := "https"
		if disableSSL {
			scheme = "http"
		}
		endpoint = fmt.Sprintf("%s://%s", scheme, endpoint)
	}

	return endpoint
}

// EnumPartitions a provides a way to retrieve the underlying partitions that
// make up the SDK's default Resolver, or any resolver decoded from a model
// file.
//
// Use this interface with DefaultResolver and DecodeModels to get the list of
// Partitions.
type EnumPartitions interface {
	Partitions() []Partition
}

// RegionsForService returns a map of regions for the partition and service.
// If either the partition or service does not exist false will be returned
// as the second parameter.
//
// This example shows how  to get the regions for DynamoDB in the AWS partition.
//    rs, exists := endpoints.RegionsForService(endpoints.DefaultPartitions(), endpoints.AwsPartitionID, endpoints.DynamodbServiceID)
//
// This is equivalent to using the partition directly.
//    rs := endpoints.AwsPartition().Services()[endpoints.DynamodbServiceID].Regions()
func RegionsForService(ps []Partition, partitionID, serviceID string) (map[string]Region, bool) {
	for _, p := range ps {
		if p.ID() != partitionID {
			continue
		}
		if _, ok := p.p.Services[serviceID]; !ok {
			break
		}

		s := Service{
			id: serviceID,
			p:  p.p,
		}
		return s.Regions(), true
	}

	return map[string]Region{}, false
}

// PartitionForRegion returns the first partition which includes the region
// passed in. This includes both known regions and regions which match
// a pattern supported by the partition which may include regions that are
// not explicitly known by the partition. Use the Regions method of the
// returned Partition if explicit support is needed.
func PartitionForRegion(ps []Partition, regionID string) (Partition, bool) {
	for _, p := range ps {
		if _, ok := p.p.Regions[regionID]; ok || p.p.RegionRegex.MatchString(regionID) {
			return p, true
		}
	}

	return Partition{}, false
}

// A Partition provides the ability to enumerate the partition's regions
// and services.
type Partition struct {
	id string
	p  *partition
}

// ID returns the identifier of the partition.
func (p Partition) ID() string { return p.id }

// EndpointFor attempts to resolve the endpoint based on service and region.
// See Options for information on configuring how the endpoint is resolved.
//
// If the service cannot be found in the metadata the UnknownServiceError
// error will be returned. This validation will occur regardless if
// StrictMatching is enabled. To enable resolving unknown services set the
// "ResolveUnknownService" option to true. When StrictMatching is disabled
// this option allows the partition resolver to resolve a endpoint based on
// the service endpoint ID provided.
//
// When resolving endpoints you can choose to enable StrictMatching. This will
// require the provided service and region to be known by the partition.
// If the endpoint cannot be strictly resolved an error will be returned. This
// mode is useful to ensure the endpoint resolved is valid. Without
// StrictMatching enabled the endpoint returned my look valid but may not work.
// StrictMatching requires the SDK to be updated if you want to take advantage
// of new regions and services expansions.
//
// Errors that can be returned.
//   * UnknownServiceError
//   * UnknownEndpointError
func (p Partition) EndpointFor(service, region string, opts ...func(*Options)) (ResolvedEndpoint, error) {
	return p.p.EndpointFor(service, region, opts...)
}

// Regions returns a map of Regions indexed by their ID. This is useful for
// enumerating over the regions in a partition.
func (p Partition) Regions() map[string]Region {
	rs := map[string]Region{}
	for id, r := range p.p.Regions {
		rs[id] = Region{
			id:   id,
			desc: r.Description,
			p:    p.p,
		}
	}

	return rs
}

// Services returns a map of Service indexed by their ID. This is useful for
// enumerating over the services in a partition.
func (p Partition) Services() map[string]Service {
	ss := map[string]Service{}
	for id := range p.p.Services {
		ss[id] = Service{
			id: id,
			p:  p.p,
		}
	}

	return ss
}

// A Region provides information about a region, and ability to resolve an
// endpoint from the context of a region, given a service.
type Region struct {
	id, desc string
	p        *partition
}

// ID returns the region's identifier.
func (r Region) ID() string { return r.id }

// Description returns the region's description. The region description
// is free text, it can be empty, and it may change between SDK releases.
func (r Region) Description() string { return r.desc }

// ResolveEndpoint resolves an endpoint from the context of the region given
// a service. See Partition.EndpointFor for usage and errors that can be returned.
func (r Region) ResolveEndpoint(service string, opts ...func(*Options)) (ResolvedEndpoint, error) {
	return r.p.EndpointFor(service, r.id, opts...)
}

// Services returns a list of all services that are known to be in this region.
func (r Region) Services() map[string]Service {
	ss := map[string]Service{}
	for id, s := range r.p.Services {
		if _, ok := s.Endpoints[r.id]; ok {
			ss[id] = Service{
				id: id,
				p:  r.p,
			}
		}
	}

	return ss
}

// A Service provides information about a service, and ability to resolve an
// endpoint from the context of a service, given a region.
type Service struct {
	id string
	p  *partition
}

// ID returns the identifier for the service.
func (s Service) ID() string { return s.id }

// ResolveEndpoint resolves an endpoint from the context of a service given
// a region. See Partition.EndpointFor for usage and errors that can be returned.
func (s Service) ResolveEndpoint(region string, opts ...func(*Options)) (ResolvedEndpoint, error) {
	return s.p.EndpointFor(s.id, region, opts...)
}

// Regions returns a map of Regions that the service is present in.
//
// A region is the AWS region the service exists in. Whereas a Endpoint is
// an URL that can be resolved to a instance of a service.
func (s Service) Regions() map[string]Region {
	rs := map[string]Region{}
	for id := range s.p.Services[s.id].Endpoints {
		if r, ok := s.p.Regions[id]; ok {
			rs[id] = Region{
				id:   id,
				desc: r.Description,
				p:    s.p,
			}
		}
	}

	return rs
}

// Endpoints returns a map of Endpoints indexed by their ID for all known
// endpoints for a service.
//
// A region is the AWS region the service exists in. Whereas a Endpoint is
// an URL that can be resolved to a instance of a service.
func (s Service) Endpoints() map[string]Endpoint {
	es := map[string]Endpoint{}
	for id := range s.p.Services[s.id].Endpoints {
		es[id] = Endpoint{
			id:        id,
			serviceID: s.id,
			p:         s.p,
		}
	}

	return es
}

// A Endpoint provides information about endpoints, and provides the ability
// to resolve that endpoint for the service, and the region the endpoint
// represents.
type Endpoint struct {
	id        string
	serviceID string
	p         *partition
}

// ID returns the identifier for an endpoint.
func (e Endpoint) ID() string { return e.id }

// ServiceID returns the identifier the endpoint belongs to.
func (e Endpoint) ServiceID() string { return e.serviceID }

// ResolveEndpoint resolves an endpoint from the context of a service and
// region the endpoint represents. See Partition.EndpointFor for usage and
// errors that can be returned.
func (e Endpoint) ResolveEndpoint(opts ...func(*Options)) (ResolvedEndpoint, error) {
	return e.p.EndpointFor(e.serviceID, e.id, opts...)
}

// A ResolvedEndpoint is an endpoint that has been resolved based on a partition
// service, and region.
type ResolvedEndpoint struct {
	// The endpoint URL
	URL string

	// The region that should be used for signing requests.
	SigningRegion string

	// The service name that should be used for signing requests.
	SigningName string

	// States that the signing name for this endpoint was derived from metadata
	// passed in, but was not explicitly modeled.
	SigningNameDerived bool

	// The signing method that should be used for signing requests.
	SigningMethod string
}

// So that the Error interface type can be included as an anonymous field
// in the requestError struct and not conflict with the error.Error() method.
type awsError awserr.Error

// A EndpointNotFoundError is returned when in StrictMatching mode, and the
// endpoint for the service and region cannot be found in any of the partitions.
type EndpointNotFoundError struct {
	awsError
	Partition string
	Service   string
	Region    string
}

// A UnknownServiceError is returned when the service does not resolve to an
// endpoint. Includes a list of all known services for the partition. Returned
// when a partition does not support the service.
type UnknownServiceError struct {
	awsError
	Partition string
	Service   string
	Known     []string
}

// NewUnknownServiceError builds and returns UnknownServiceError.
func NewUnknownServiceError(p, s string, known []string) UnknownServiceError {
	return UnknownServiceError{
		awsError: awserr.New("UnknownServiceError",
			"could not resolve endpoint for unknown service", nil),
		Partition: p,
		Service:   s,
		Known:     known,
	}
}

// String returns the string representation of the error.
func (e UnknownServiceError) Error() string {
	extra := fmt.Sprintf("partition: %q, service: %q",
		e.Partition, e.Service)
	if len(e.Known) > 0 {
		extra += fmt.Sprintf(", known: %v", e.Known)
	}
	return awserr.SprintError(e.Code(), e.Message(), extra, e.OrigErr())
}

// String returns the string representation of the error.
func (e UnknownServiceError) String() string {
	return e.Error()
}

// A UnknownEndpointError is returned when in StrictMatching mode and the
// service is valid, but the region does not resolve to an endpoint. Includes
// a list of all known endpoints for the service.
type UnknownEndpointError struct {
	awsError
	Partition string
	Service   string
	Region    string
	Known     []string
}

// NewUnknownEndpointError builds and returns UnknownEndpointError.
func NewUnknownEndpointError(p, s, r string, known []string) UnknownEndpointError {
	return UnknownEndpointError{
		awsError: awserr.New("UnknownEndpointError",
			"could not resolve endpoint", nil),
		Partition: p,
		Service:   s,
		Region:    r,
		Known:     known,
	}
}

// String returns the string representation of the error.
func (e UnknownEndpointError) Error() string {
	extra := fmt.Sprintf("partition: %q, service: %q, region: %q",
		e.Partition, e.Service, e.Region)
	if len(e.Known) > 0 {
		extra += fmt.Sprintf(", known: %v", e.Known)
	}
	return awserr.SprintError(e.Code(), e.Message(), extra, e.OrigErr())
}

// String returns the string representation of the error.
func (e UnknownEndpointError) String() string {
	return e.Error()
}
