/*
 * 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 resolver

import (
	"errors"
	"log"
	"net/url"

	"fmt"
	"github.com/go-chassis/go-chassis/core/lager"
	"github.com/go-mesh/mesher/config"
)

var drMap = make(map[string]DestinationResolver)

//DestinationResolverPlugins is a map
var DestinationResolverPlugins map[string]func() DestinationResolver

//SelfEndpoint is a string
var SelfEndpoint = "#To be init#"

//DefaultPlugin is a contant which stores default plugin name
const DefaultPlugin = "host"

//ErrUnknownResolver is of type error
var ErrUnknownResolver = errors.New("unknown Destination Resolver")

//DestinationResolver is a interface with Resolve method
type DestinationResolver interface {
	Resolve(sourceAddr string, header map[string]string, rawURI string, destinationName *string) (string, error)
}

//DefaultDestinationResolver is a struct
type DefaultDestinationResolver struct {
}

//Resolve resolves service's endpoint
//service may have multiple port for same protocol
func (dr *DefaultDestinationResolver) Resolve(sourceAddr string, header map[string]string, rawURI string, destinationName *string) (string, error) {
	u, err := url.Parse(rawURI)
	if err != nil {
		lager.Logger.Error("Can not parse url: " + err.Error())
		return "", err
	}

	if u.Host == "" {
		return "", errors.New(`Invalid uri, please check:
1, For provider, mesher listens on external ip
2, Set http_proxy as mesher address, before sending request`)
	}

	if u.Host == SelfEndpoint {
		return "", errors.New(`uri format must be: http://serviceName/api`)
	}

	*destinationName = u.Hostname()
	return u.Port(), nil
}

//New function returns new DefaultDestinationResolver struct object
func New() DestinationResolver {
	return &DefaultDestinationResolver{}
}

//GetDestinationResolver returns destinationResolver pointer
func GetDestinationResolver(name string) DestinationResolver {
	return drMap[name]
}

//InstallDestinationResolverPlugin function installs new plugin
func InstallDestinationResolverPlugin(name string, newFunc func() DestinationResolver) {
	DestinationResolverPlugins[name] = newFunc
	log.Printf("Installed DestinationResolver Plugin, name=%s", name)
}

//SetDefaultDestinationResolver set the a default implementation for a protocol, so that you don't need to set config file
func SetDefaultDestinationResolver(name string, dr DestinationResolver) {
	drMap[name] = dr
	log.Printf("Installed default DestinationResolver for [%s]", name)
}
func init() {
	DestinationResolverPlugins = make(map[string]func() DestinationResolver)
	InstallDestinationResolverPlugin(DefaultPlugin, New)
	SetDefaultDestinationResolver("http", &DefaultDestinationResolver{})
}

//Init function reads config and initiates it
func Init() error {
	if config.GetConfig().Plugin != nil {
		for name, v := range config.GetConfig().Plugin.DestinationResolver {
			if v == "" {
				v = DefaultPlugin
			}
			f, ok := DestinationResolverPlugins[v]
			if !ok {
				return fmt.Errorf("unknown destination resolver [%s]", v)
			}
			drMap[name] = f()
		}
	}

	return nil
}
