/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package xds

import (
	"fmt"
	"strings"
)

import (
	"github.com/pkg/errors"
)

import (
	mesh_proto "github.com/apache/dubbo-kubernetes/api/mesh/v1alpha1"
	core_mesh "github.com/apache/dubbo-kubernetes/pkg/core/resources/apis/mesh"
	core_model "github.com/apache/dubbo-kubernetes/pkg/core/resources/model"
)

type APIVersion string

// StreamID represents a stream opened by XDS
type StreamID = int64

type ProxyId struct {
	mesh string
	name string
}

func (id *ProxyId) String() string {
	return fmt.Sprintf("%s.%s", id.mesh, id.name)
}

func (id *ProxyId) ToResourceKey() core_model.ResourceKey {
	return core_model.ResourceKey{
		Name: id.name,
		Mesh: id.mesh,
	}
}

// ServiceName is a convenience type alias to clarify the meaning of string value.
type ServiceName = string

type MeshName = string

// TagSelectorSet is a set of unique TagSelectors.
type TagSelectorSet []mesh_proto.TagSelector

// DestinationMap holds a set of selectors for all reachable Dataplanes grouped by service name.
// DestinationMap is based on ServiceName and not on the OutboundInterface because TrafficRoute can introduce new service destinations that were not included in a outbound section.
// Policies that match on outbound connections also match by service destination name and not outbound interface for the same reason.
type DestinationMap map[ServiceName]TagSelectorSet

type ExternalService struct {
	TLSEnabled               bool
	CaCert                   []byte
	ClientCert               []byte
	ClientKey                []byte
	AllowRenegotiation       bool
	SkipHostnameVerification bool
	ServerName               string
}

type Locality struct {
	Zone     string
	SubZone  string
	Priority uint32
	Weight   uint32
}

// Endpoint holds routing-related information about a single endpoint.
type Endpoint struct {
	Target          string
	UnixDomainPath  string
	Port            uint32
	Tags            map[string]string
	Weight          uint32
	Locality        *Locality
	ExternalService *ExternalService
}

func (e Endpoint) Address() string {
	return fmt.Sprintf("%s:%d", e.Target, e.Port)
}

// EndpointList is a list of Endpoints with convenience methods.
type EndpointList []Endpoint

// EndpointMap holds routing-related information about a set of endpoints grouped by service name.
type EndpointMap map[ServiceName][]Endpoint

// SocketAddressProtocol is the L4 protocol the listener should bind to
type SocketAddressProtocol int32

const (
	SocketAddressProtocolTCP SocketAddressProtocol = 0
	SocketAddressProtocolUDP SocketAddressProtocol = 1
)

// Proxy contains required data for generating XDS config that is specific to a data plane proxy.
// The data that is specific for the whole mesh should go into MeshContext.
type Proxy struct {
	Id         ProxyId
	APIVersion APIVersion
	Dataplane  *core_mesh.DataplaneResource
	Metadata   *DataplaneMetadata
	Routing    Routing
	Policies   MatchedPolicies

	// SecretsTracker allows us to track when a generator references a secret so
	// we can be sure to include only those secrets later on.
	SecretsTracker SecretsTracker

	// ZoneIngressProxy is available only when XDS is generated for ZoneIngress data plane proxy.
	ZoneIngressProxy *ZoneIngressProxy
	// RuntimeExtensions a set of extensions to add for custom extensions
	RuntimeExtensions map[string]interface{}
	// Zone the zone the proxy is in
	Zone string
}

type ServerSideTLSCertPaths struct {
	CertPath string
	KeyPath  string
}

type IdentityCertRequest interface {
	Name() string
}

type CaRequest interface {
	MeshName() []string
	Name() string
}

// SecretsTracker provides a way to ask for a secret and keeps track of which are
// used, so that they can later be generated and included in the resources.
type SecretsTracker interface {
	RequestIdentityCert() IdentityCertRequest
	RequestCa(mesh string) CaRequest
	RequestAllInOneCa() CaRequest

	UsedIdentity() bool
	UsedCas() map[string]struct{}
	UsedAllInOne() bool
}

type ExternalServiceDynamicPolicies map[ServiceName]PluginOriginatedPolicies

type MeshIngressResources struct {
	EndpointMap EndpointMap
	Resources   map[core_model.ResourceType]core_model.ResourceList
}

type ZoneIngressProxy struct {
	ZoneIngressResource *core_mesh.ZoneIngressResource
	MeshResourceList    []*MeshIngressResources
}

type Routing struct {
	OutboundTargets EndpointMap
	// ExternalServiceOutboundTargets contains endpoint map for direct access of external services (without egress)
	// Since we take into account TrafficPermission to exclude external services from the map,
	// it is specific for each data plane proxy.
	ExternalServiceOutboundTargets EndpointMap
}

func (s TagSelectorSet) Add(new mesh_proto.TagSelector) TagSelectorSet {
	for _, old := range s {
		if new.Equal(old) {
			return s
		}
	}
	return append(s, new)
}

func (s TagSelectorSet) Matches(tags map[string]string) bool {
	for _, selector := range s {
		if selector.Matches(tags) {
			return true
		}
	}
	return false
}

func (e Endpoint) IsExternalService() bool {
	return e.ExternalService != nil
}

func (e Endpoint) LocalityString() string {
	if e.Locality == nil {
		return ""
	}
	return fmt.Sprintf("%s:%s", e.Locality.Zone, e.Locality.SubZone)
}

func (e Endpoint) HasLocality() bool {
	return e.Locality != nil
}

// ContainsTags returns 'true' if for every key presented both in 'tags' and 'Endpoint#Tags'
// values are equal
func (e Endpoint) ContainsTags(tags map[string]string) bool {
	for otherKey, otherValue := range tags {
		endpointValue, ok := e.Tags[otherKey]
		if !ok || otherValue != endpointValue {
			return false
		}
	}
	return true
}

func (l EndpointList) Filter(selector mesh_proto.TagSelector) EndpointList {
	var endpoints EndpointList
	for _, endpoint := range l {
		if selector.Matches(endpoint.Tags) {
			endpoints = append(endpoints, endpoint)
		}
	}
	return endpoints
}

// if false endpoint should be accessed through zoneIngress of other zone
func (e Endpoint) IsReachableFromZone(localZone string) bool {
	return e.Locality == nil || e.Locality.Zone == "" || e.Locality.Zone == localZone
}

func BuildProxyId(mesh, name string) *ProxyId {
	return &ProxyId{
		name: name,
		mesh: mesh,
	}
}

func ParseProxyIdFromString(id string) (*ProxyId, error) {
	if id == "" {
		return nil, errors.Errorf("Envoy ID must not be nil")
	}
	parts := strings.SplitN(id, ".", 2)
	mesh := parts[0]
	// when proxy is an ingress mesh is empty
	if len(parts) < 2 {
		return nil, errors.New("the name should be provided after the dot")
	}
	name := parts[1]
	if name == "" {
		return nil, errors.New("name must not be empty")
	}
	return &ProxyId{
		mesh: mesh,
		name: name,
	}, nil
}

func FromResourceKey(key core_model.ResourceKey) ProxyId {
	return ProxyId{
		mesh: key.Mesh,
		name: key.Name,
	}
}
