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

import (
	"bytes"
	"encoding/json"
	"io/ioutil"
	"net/url"
	"reflect"
	"strconv"
	"strings"
	"time"
)

import (
	"github.com/dubbogo/dubbo-go-pixiu-filter/pkg/api/config"
	"github.com/pkg/errors"
	"github.com/spf13/cast"
)

import (
	"github.com/apache/dubbo-go-pixiu/pkg/client"
	"github.com/apache/dubbo-go-pixiu/pkg/common/constant"
	"github.com/apache/dubbo-go-pixiu/pkg/router"
)

var mappers = map[string]client.ParamMapper{
	constant.QueryStrings: queryStringsMapper{},
	constant.Headers:      headerMapper{},
	constant.RequestBody:  bodyMapper{},
	constant.RequestURI:   uriMapper{},
}

type dubboTarget struct {
	Values []interface{} // the slice contains the parameters.
	Types  []string      // the slice contains the parameters' types. It should match the values one by one.
}

// pre-allocate proper memory according to the params' usability.
func newDubboTarget(mps []config.MappingParam) *dubboTarget {
	length := 0

	for i := 0; i < len(mps); i++ {
		isGeneric, v := getGenericMapTo(mps[i].MapTo)
		if isGeneric && v != optionKeyValues {
			continue
		}
		length++
	}

	if length > 0 {
		val := make([]interface{}, length)
		target := &dubboTarget{
			Values: val,
			Types:  make([]string, length),
		}
		return target
	}
	return nil
}

type queryStringsMapper struct{}

// nolint
func (qm queryStringsMapper) Map(mp config.MappingParam, c *client.Request, target interface{}, option client.RequestOption) error {
	t, err := validateTarget(target)
	if err != nil {
		return err
	}
	queryValues, err := url.ParseQuery(c.IngressRequest.URL.RawQuery)
	if err != nil {
		return errors.Wrap(err, "Error happened when parsing the query paramters")
	}
	_, key, err := client.ParseMapSource(mp.Name)
	if err != nil {
		return err
	}
	pos, err := strconv.Atoi(mp.MapTo)
	if err != nil && option == nil {
		return errors.Errorf("Parameter mapping %v incorrect", mp)
	}
	qValue := queryValues.Get(key[0])
	if len(qValue) == 0 {
		return errors.Errorf("Query parameter %s does not exist", key)
	}

	return setTargetWithOpt(c, option, t, pos, qValue, mp.MapType)
}

type headerMapper struct{}

// nolint
func (hm headerMapper) Map(mp config.MappingParam, c *client.Request, target interface{}, option client.RequestOption) error {
	rv, err := validateTarget(target)
	if err != nil {
		return err
	}
	_, key, err := client.ParseMapSource(mp.Name)
	pos, err := strconv.Atoi(mp.MapTo)
	if err != nil && option == nil {
		return errors.Errorf("Parameter mapping %+v incorrect", mp)
	}
	header := c.IngressRequest.Header.Get(key[0])
	if len(header) == 0 {
		return errors.Errorf("Header %s not found", key[0])
	}

	return setTargetWithOpt(c, option, rv, pos, header, mp.MapType)
}

type bodyMapper struct{}

// nolint
func (bm bodyMapper) Map(mp config.MappingParam, c *client.Request, target interface{}, option client.RequestOption) error {
	// TO-DO: add support for content-type other than application/json
	rv, err := validateTarget(target)
	if err != nil {
		return err
	}
	_, keys, err := client.ParseMapSource(mp.Name)
	if err != nil {
		return err
	}
	pos, err := strconv.Atoi(mp.MapTo)
	if err != nil && option == nil {
		return errors.Errorf("Parameter mapping %v incorrect, parameters for Dubbo backend must be mapped to an int to represent position", mp)
	}

	rawBody, err := ioutil.ReadAll(c.IngressRequest.Body)
	defer func() {
		c.IngressRequest.Body = ioutil.NopCloser(bytes.NewReader(rawBody))
	}()
	if err != nil {
		return err
	}
	mapBody := map[string]interface{}{}
	json.Unmarshal(rawBody, &mapBody)
	val, err := client.GetMapValue(mapBody, keys)

	if err := setTargetWithOpt(c, option, rv, pos, val, mp.MapType); err != nil {
		return errors.Wrap(err, "set target fail")
	}

	c.IngressRequest.Body = ioutil.NopCloser(bytes.NewBuffer(rawBody))
	return nil
}

type uriMapper struct{}

// nolint
func (um uriMapper) Map(mp config.MappingParam, c *client.Request, target interface{}, option client.RequestOption) error {
	rv, err := validateTarget(target)
	if err != nil {
		return err
	}
	_, keys, err := client.ParseMapSource(mp.Name)
	if err != nil {
		return err
	}
	pos, err := strconv.Atoi(mp.MapTo)
	if err != nil && option == nil {
		return errors.Errorf("Parameter mapping %v incorrect", mp)
	}
	uriValues := router.GetURIParams(&c.API, *c.IngressRequest.URL)

	return setTargetWithOpt(c, option, rv, pos, uriValues.Get(keys[0]), mp.MapType)
}

// validateTarget verify if the incoming target for the Map function
// can be processed as expected.
func validateTarget(target interface{}) (*dubboTarget, error) {
	val, ok := target.(*dubboTarget)
	if !ok {
		return nil, errors.New("Target params for dubbo backend must be *dubbogoTarget")
	}
	return val, nil
}

func setTargetWithOpt(req *client.Request, option client.RequestOption,
	target *dubboTarget, pos int, value interface{}, targetType string) error {
	if option != nil {
		return setGenericTarget(req, option, target, value, targetType)
	}
	value, err := mapTypes(targetType, value)
	if err != nil {
		return err
	}
	setCommonTarget(target, pos, value, targetType)
	return nil
}

func setGenericTarget(req *client.Request, option client.RequestOption,
	target *dubboTarget, value interface{}, targetType string) error {
	var err error
	switch option.(type) {
	case *groupOpt, *versionOpt, *interfaceOpt, *applicationOpt, *methodOpt:
		err = option.Action(req, value)
	case *valuesOpt:
		err = option.Action(target, [2]interface{}{value, targetType})
	case *paramTypesOpt:
		err = option.Action(target, value)
	}
	return err
}

func setCommonTarget(target *dubboTarget, pos int, value interface{}, targetType string) {
	// if the mapTo position is greater than the numbers of usable parameters,
	// extend the values and types slices. It changes the address of the the target.
	if cap(target.Values) <= pos {
		list := make([]interface{}, pos+1-len(target.Values))
		typeList := make([]string, pos+1-len(target.Types))
		target.Values = append(target.Values, list...)
		target.Types = append(target.Types, typeList...)
	}
	target.Values[pos] = value
	target.Types[pos] = targetType
}

func mapTypes(jType string, originVal interface{}) (interface{}, error) {
	targetType, ok := constant.JTypeMapper[jType]
	if !ok {
		return nil, errors.Errorf("Invalid parameter type: %s", jType)
	}
	switch targetType {
	case reflect.TypeOf(""):
		return cast.ToStringE(originVal)
	case reflect.TypeOf(int(0)):
		return cast.ToIntE(originVal)
	case reflect.TypeOf(int8(0)):
		return cast.ToInt8E(originVal)
	case reflect.TypeOf(int16(16)):
		return cast.ToInt16E(originVal)
	case reflect.TypeOf(int32(0)):
		return cast.ToInt32E(originVal)
	case reflect.TypeOf(int64(0)):
		return cast.ToInt64E(originVal)
	case reflect.TypeOf(float32(0)):
		return cast.ToFloat32E(originVal)
	case reflect.TypeOf(float64(0)):
		return cast.ToFloat64E(originVal)
	case reflect.TypeOf(true):
		return cast.ToBoolE(originVal)
	case reflect.TypeOf(time.Time{}):
		return cast.ToTimeE(originVal)
	default:
		return originVal, nil
	}
}

// getGenericMapTo will parse the mapTo field, if the mapTo value is
// opt.xxx, the "opt." prefix will identify the param mapTo generic field,
// supporting generic fields: interface, group, application, method, version,
// values, types
func getGenericMapTo(mapTo string) (isGeneric bool, genericField string) {
	fields := strings.Split(mapTo, ".")
	if len(fields) != 2 || fields[0] != "opt" {
		return false, ""
	}
	if _, ok := DefaultMapOption[fields[1]]; !ok {
		return false, ""
	}
	return true, fields[1]
}
