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

import (
	"encoding/json"
	"fmt"
	"io/ioutil"
	"os/exec"
	"strings"
	"time"

	"github.com/apisix/manager-api/conf"
	"github.com/apisix/manager-api/errno"
	"github.com/apisix/manager-api/log"
	"github.com/apisix/manager-api/utils"
	uuid "github.com/satori/go.uuid"
)

const (
	ContentType      = "application/json"
	HTTP             = "http"
	HTTPS            = "https"
	SCHEME           = "scheme"
	WEBSOCKET        = "websocket"
	REDIRECT         = "redirect"
	PROXY_REWRIETE   = "proxy-rewrite"
	UPATHTYPE_STATIC = "static"
	UPATHTYPE_REGX   = "regx"
	UPATHTYPE_KEEP   = "keep"
)

var logger = log.GetLogger()

func (r *RouteRequest) Parse(body interface{}) error {
	if err := json.Unmarshal(body.([]byte), r); err != nil {
		r = nil
		return err
	} else {
		if r.Uris == nil || len(r.Uris) < 1 {
			r.Uris = []string{"/*"}
		}
		if len(strings.Trim(r.RouteGroupId, "")) > 0 {
			routeGroup := &RouteGroupDao{}
			if err, _ := routeGroup.FindRouteGroup(r.RouteGroupId); err != nil {
				return err
			}
			r.RouteGroupName = routeGroup.Name
		}
	}
	return nil
}

func (arr *ApisixRouteRequest) Parse(r *RouteRequest) {
	arr.Desc = r.Desc
	arr.Priority = r.Priority
	arr.Methods = r.Methods
	arr.Uris = r.Uris
	arr.Hosts = r.Hosts
	arr.Vars = r.Vars
	arr.Upstream = r.Upstream
	arr.Plugins = r.Plugins
}

func (rd *Route) Parse(r *RouteRequest, arr *ApisixRouteRequest) error {
	//rd.Name = arr.Name
	rd.Description = arr.Desc
	rd.UpstreamId = r.UpstreamId
	rd.RouteGroupId = r.RouteGroupId
	rd.RouteGroupName = r.RouteGroupName
	rd.Status = r.Status
	if content, err := json.Marshal(r); err != nil {
		return err
	} else {
		rd.Content = string(content)
	}
	if script, err := json.Marshal(r.Script); err != nil {
		return err
	} else {
		rd.Script = string(script)
	}
	timestamp := time.Now().Unix()
	rd.CreateTime = timestamp
	rd.Priority = r.Priority
	return nil
}

func (arr *ApisixRouteRequest) FindById(rid string) (*ApisixRouteResponse, error) {
	url := fmt.Sprintf("%s/routes/%s", conf.BaseUrl, rid)
	if resp, err := utils.Get(url); err != nil {
		logger.Error(err.Error())
		return nil, err
	} else {
		var arresp ApisixRouteResponse
		if err := json.Unmarshal(resp, &arresp); err != nil {
			logger.Error(err.Error())
			return nil, err
		} else {
			return &arresp, nil
		}
	}
}

func (arr *ApisixRouteRequest) Update(rid string) (*ApisixRouteResponse, error) {
	url := fmt.Sprintf("%s/routes/%s", conf.BaseUrl, rid)
	if b, err := json.Marshal(arr); err != nil {
		return nil, err
	} else {
		fmt.Println(string(b))
		if resp, err := utils.Put(url, b); err != nil {
			logger.Error(err.Error())
			return nil, err
		} else {
			var arresp ApisixRouteResponse
			if err := json.Unmarshal(resp, &arresp); err != nil {
				logger.Error(err.Error())
				return nil, err
			} else {
				return &arresp, nil
			}
		}
	}
}

func (arr *ApisixRouteRequest) Create(rid string) (*ApisixRouteResponse, error) {
	url := fmt.Sprintf("%s/routes/%s", conf.BaseUrl, rid)
	if b, err := json.Marshal(arr); err != nil {
		return nil, err
	} else {
		fmt.Println(string(b))
		if resp, err := utils.Put(url, b); err != nil {
			logger.Error(err.Error())
			return nil, err
		} else {
			var arresp ApisixRouteResponse
			if err := json.Unmarshal(resp, &arresp); err != nil {
				logger.Error(err.Error())
				return nil, err
			} else {
				return &arresp, nil
			}
		}
	}
}

func (arr *ApisixRouteRequest) Delete(rid string) (*ApisixRouteResponse, error) {
	url := fmt.Sprintf("%s/routes/%s", conf.BaseUrl, rid)
	if resp, err := utils.Delete(url); err != nil {
		logger.Error(err.Error())
		return nil, err
	} else {
		var arresp ApisixRouteResponse
		if err := json.Unmarshal(resp, &arresp); err != nil {
			logger.Error(err.Error())
			return nil, err
		} else {
			return &arresp, nil
		}
	}
}

type RouteRequest struct {
	ID               string                 `json:"id,omitempty"`
	Name             string                 `json:"name"`
	Desc             string                 `json:"desc,omitempty"`
	Priority         int64                  `json:"priority,omitempty"`
	Methods          []string               `json:"methods,omitempty"`
	Uris             []string               `json:"uris"`
	Hosts            []string               `json:"hosts,omitempty"`
	Protocols        []string               `json:"protocols,omitempty"`
	Redirect         *Redirect              `json:"redirect,omitempty"`
	Vars             [][]string             `json:"vars,omitempty"`
	Upstream         *Upstream              `json:"upstream,omitempty"`
	UpstreamId       string                 `json:"upstream_id,omitempty"`
	UpstreamProtocol string                 `json:"upstream_protocol,omitempty"`
	UpstreamPath     *UpstreamPath          `json:"upstream_path,omitempty"`
	UpstreamHeader   map[string]string      `json:"upstream_header,omitempty"`
	Plugins          map[string]interface{} `json:"plugins"`
	Script           map[string]interface{} `json:"script"`
	RouteGroupId     string                 `json:"route_group_id"`
	RouteGroupName   string                 `json:"route_group_name"`
	Status           bool                   `json:"status"`
}

func (r *ApisixRouteResponse) Parse() (*RouteRequest, error) {
	o := r.Node.Value

	//Protocols from vars and upstream
	protocols := make([]string, 0)
	if o.Upstream != nil && o.Upstream.EnableWebsocket {
		protocols = append(protocols, WEBSOCKET)
	}
	if o.UpstreamId != "" {
		protocols = append(protocols, WEBSOCKET)
	}
	flag := true
	for _, t := range o.Vars {
		if t[0] == SCHEME {
			flag = false
			protocols = append(protocols, t[2])
		}
	}
	if flag {
		protocols = append(protocols, HTTP)
		protocols = append(protocols, HTTPS)
	}
	//Redirect from plugins
	redirect := &Redirect{}
	upstreamProtocol := UPATHTYPE_KEEP
	upstreamHeader := make(map[string]string)
	upstreamPath := &UpstreamPath{}
	for k, v := range o.Plugins {
		if k == REDIRECT {
			if bytes, err := json.Marshal(v); err != nil {
				return nil, err
			} else {
				if err := json.Unmarshal(bytes, redirect); err != nil {
					return nil, err
				}
			}

		}
		if k == PROXY_REWRIETE {
			pr := &ProxyRewrite{}
			if bytes, err := json.Marshal(v); err != nil {
				return nil, err
			} else {
				if err := json.Unmarshal(bytes, pr); err != nil {
					return nil, err
				} else {
					if pr.Scheme != "" {
						upstreamProtocol = pr.Scheme
					}
					upstreamHeader = pr.Headers
					if (pr.RegexUri == nil || len(pr.RegexUri) < 2) && pr.Uri == "" {
						upstreamPath = nil
					} else if pr.RegexUri == nil || len(pr.RegexUri) < 2 {
						upstreamPath.UPathType = UPATHTYPE_STATIC
						upstreamPath.To = pr.Uri
					} else {
						upstreamPath.UPathType = UPATHTYPE_REGX
						upstreamPath.From = pr.RegexUri[0]
						upstreamPath.To = pr.RegexUri[1]
					}
				}
			}
		}
	}
	//Vars
	requestVars := make([][]string, 0)
	for _, t := range o.Vars {
		if t[0] != SCHEME {
			requestVars = append(requestVars, t)
		}
	}
	//Plugins
	requestPlugins := utils.CopyMap(o.Plugins)
	delete(requestPlugins, REDIRECT)
	delete(requestPlugins, PROXY_REWRIETE)

	// check if upstream is not exist
	if o.Upstream == nil && o.UpstreamId == "" {
		upstreamProtocol = ""
		upstreamHeader = nil
		upstreamPath = nil
	}
	if upstreamPath != nil && upstreamPath.UPathType == "" {
		upstreamPath = nil
	}
	result := &RouteRequest{
		ID:               o.Id,
		Desc:             o.Desc,
		Priority:         o.Priority,
		Methods:          o.Methods,
		Uris:             o.Uris,
		Hosts:            o.Hosts,
		Redirect:         redirect,
		Upstream:         o.Upstream,
		UpstreamId:       o.UpstreamId,
		RouteGroupId:     o.RouteGroupId,
		UpstreamProtocol: upstreamProtocol,
		UpstreamPath:     upstreamPath,
		UpstreamHeader:   upstreamHeader,
		Protocols:        protocols,
		Vars:             requestVars,
		Plugins:          requestPlugins,
	}
	return result, nil
}

type Redirect struct {
	HttpToHttps bool   `json:"http_to_https,omitempty"`
	Code        int64  `json:"code,omitempty"`
	Uri         string `json:"uri,omitempty"`
}

type ProxyRewrite struct {
	Uri      string            `json:"uri"`
	RegexUri []string          `json:"regex_uri"`
	Scheme   string            `json:"scheme"`
	Host     string            `json:"host"`
	Headers  map[string]string `json:"headers"`
}

func (r ProxyRewrite) MarshalJSON() ([]byte, error) {
	m := make(map[string]interface{})
	if r.RegexUri != nil {
		m["regex_uri"] = r.RegexUri
	}
	if r.Uri != "" {
		m["uri"] = r.Uri
	}
	if r.Scheme != UPATHTYPE_KEEP && r.Scheme != "" {
		m["scheme"] = r.Scheme
	}
	if r.Host != "" {
		m["host"] = r.Host
	}
	if r.Headers != nil && len(r.Headers) > 0 {
		m["headers"] = r.Headers
	}
	if result, err := json.Marshal(m); err != nil {
		return nil, err
	} else {
		return result, nil
	}
}

func (r Redirect) MarshalJSON() ([]byte, error) {
	m := make(map[string]interface{})
	if r.HttpToHttps {
		m["http_to_https"] = true
	} else if r.Uri != "" {
		m["code"] = r.Code
		m["uri"] = r.Uri
	}
	if result, err := json.Marshal(m); err != nil {
		return nil, err
	} else {
		return result, nil
	}
}

type Upstream struct {
	UType           string                 `json:"type"`
	Nodes           map[string]int64       `json:"nodes"`
	Timeout         UpstreamTimeout        `json:"timeout"`
	EnableWebsocket bool                   `json:"enable_websocket"`
	Checks          map[string]interface{} `json:"checks,omitempty"`
	HashOn          string                 `json:"hash_on,omitempty"`
	Key             string                 `json:"key,omitempty"`
}

type UpstreamTimeout struct {
	Connect int64 `json:"connect"`
	Send    int64 `json:"send"`
	Read    int64 `json:"read"`
}

type UpstreamPath struct {
	UPathType string `json:"type"`
	From      string `json:"from"`
	To        string `json:"to"`
}

type ApisixRouteRequest struct {
	Desc       string                 `json:"desc,omitempty"`
	Priority   int64                  `json:"priority"`
	Methods    []string               `json:"methods,omitempty"`
	Uris       []string               `json:"uris,omitempty"`
	Hosts      []string               `json:"hosts,omitempty"`
	Vars       [][]string             `json:"vars,omitempty"`
	Upstream   *Upstream              `json:"upstream,omitempty"`
	UpstreamId string                 `json:"upstream_id,omitempty"`
	Plugins    map[string]interface{} `json:"plugins,omitempty"`
	Script     string                 `json:"script,omitempty"`
	//Name     string                 `json:"name"`
}

// ApisixRouteResponse is response from apisix admin api
type ApisixRouteResponse struct {
	Action string `json:"action"`
	Node   *Node  `json:"node"`
}

type Node struct {
	Value         Value  `json:"value"`
	ModifiedIndex uint64 `json:"modifiedIndex"`
}

type Value struct {
	Id             string                 `json:"id"`
	Name           string                 `json:"name"`
	Desc           string                 `json:"desc,omitempty"`
	Priority       int64                  `json:"priority"`
	Methods        []string               `json:"methods"`
	Uris           []string               `json:"uris"`
	Hosts          []string               `json:"hosts"`
	Vars           [][]string             `json:"vars"`
	Upstream       *Upstream              `json:"upstream,omitempty"`
	UpstreamId     string                 `json:"upstream_id,omitempty"`
	Plugins        map[string]interface{} `json:"plugins"`
	RouteGroupId   string                 `json:"route_group_id"`
	RouteGroupName string                 `json:"route_group_name"`
	Status         bool                   `json:"status"`
}

type Route struct {
	Base
	Name            string `json:"name"`
	Description     string `json:"description,omitempty"`
	Hosts           string `json:"hosts"`
	Uris            string `json:"uris"`
	UpstreamNodes   string `json:"upstream_nodes"`
	UpstreamId      string `json:"upstream_id"`
	Priority        int64  `json:"priority"`
	Content         string `json:"content"`
	Script          string `json:"script"`
	ContentAdminApi string `json:"content_admin_api"`
	RouteGroupId    string `json:"route_group_id"`
	RouteGroupName  string `json:"route_group_name"`
	Status          bool   `json:"status"`
}

type RouteResponse struct {
	Base
	Name           string    `json:"name"`
	Description    string    `json:"description,omitempty"`
	Hosts          []string  `json:"hosts,omitempty"`
	Uris           []string  `json:"uris,omitempty"`
	Upstream       *Upstream `json:"upstream,omitempty"`
	UpstreamId     string    `json:"upstream_id,omitempty"`
	Priority       int64     `json:"priority"`
	RouteGroupId   string    `json:"route_group_id"`
	RouteGroupName string    `json:"route_group_name"`
	Status         bool      `json:"status"`
}

type RouteResponseWithUrl struct {
	RouteRequest
	Url string `json:"url"`
}

type ListResponse struct {
	Count int         `json:"count"`
	Data  interface{} `json:"data"`
}

func (rr *RouteResponse) Parse(r *Route) {
	rr.Base = r.Base
	rr.Name = r.Name
	rr.Description = r.Description
	rr.UpstreamId = r.UpstreamId
	rr.Priority = r.Priority
	rr.RouteGroupId = r.RouteGroupId
	rr.RouteGroupName = r.RouteGroupName
	rr.Status = r.Status
	// hosts
	if len(r.Hosts) > 0 {
		var hosts []string
		if err := json.Unmarshal([]byte(r.Hosts), &hosts); err == nil {
			rr.Hosts = hosts
		} else {
			logger.Error(err.Error())
		}
	}

	// uris
	if len(r.Uris) > 0 {
		var uris []string
		if err := json.Unmarshal([]byte(r.Uris), &uris); err == nil {
			rr.Uris = uris
		}
	}

	// uris
	var resp ApisixRouteResponse
	if err := json.Unmarshal([]byte(r.ContentAdminApi), &resp); err == nil {
		rr.Upstream = resp.Node.Value.Upstream
	}
}

// RouteRequest -> ApisixRouteRequest
func ToApisixRequest(routeRequest *RouteRequest) *ApisixRouteRequest {
	// redirect -> plugins
	plugins := utils.CopyMap(routeRequest.Plugins)
	redirect := routeRequest.Redirect
	if redirect != nil {
		plugins["redirect"] = redirect
	}

	logger.Info(routeRequest.Plugins)

	// scheme https and not http -> vars ['scheme', '==', 'https']
	pMap := utils.Set2Map(routeRequest.Protocols)

	arr := &ApisixRouteRequest{}
	arr.Parse(routeRequest)

	// protocols[websokect] -> upstream
	if pMap[WEBSOCKET] == 1 && arr.Upstream != nil {
		arr.Upstream.EnableWebsocket = true
	}
	vars := utils.CopyStrings(routeRequest.Vars)
	if pMap[HTTP] != 1 || pMap[HTTPS] != 1 {
		if pMap[HTTP] == 1 {
			vars = append(vars, []string{SCHEME, "==", HTTP})
		}
		if pMap[HTTPS] == 1 {
			vars = append(vars, []string{SCHEME, "==", HTTPS})
		}
	}
	if len(vars) > 0 {
		arr.Vars = vars
	} else {
		arr.Vars = nil
	}
	// upstreamId
	arr.UpstreamId = routeRequest.UpstreamId
	// upstream protocol
	if arr.Upstream != nil || arr.UpstreamId != "" {
		pr := &ProxyRewrite{}
		pr.Scheme = routeRequest.UpstreamProtocol
		// upstream path
		proxyPath := routeRequest.UpstreamPath
		if proxyPath != nil {
			if proxyPath.UPathType == UPATHTYPE_STATIC || proxyPath.UPathType == "" {
				pr.Uri = proxyPath.To
				pr.RegexUri = nil
			} else {
				pr.RegexUri = []string{proxyPath.From, proxyPath.To}
			}
		}
		// upstream headers
		pr.Headers = routeRequest.UpstreamHeader
		if proxyPath != nil || pr.Scheme != UPATHTYPE_KEEP || (pr.Headers != nil && len(pr.Headers) > 0) {
			plugins[PROXY_REWRIETE] = pr
		}
	}

	if plugins != nil && len(plugins) > 0 {
		arr.Plugins = plugins
	} else {
		arr.Plugins = nil
	}

	if routeRequest.Script != nil {
		arr.Script, _ = generateLuaCode(routeRequest.Script)
	}

	return arr
}

func generateLuaCode(script map[string]interface{}) (string, error) {
	scriptString, err := json.Marshal(script)
	if err != nil {
		return "", err
	}

	cmd := exec.Command("sh", "-c",
		"cd /go/manager-api/dag-to-lua/ && lua cli.lua "+
			"'"+string(scriptString)+"'")

	logger.Info("generate conf:", string(scriptString))

	stdout, _ := cmd.StdoutPipe()
	defer stdout.Close()
	if err := cmd.Start(); err != nil {
		logger.Info("generate err:", err)
		return "", err
	}

	result, _ := ioutil.ReadAll(stdout)
	resData := string(result)

	logger.Info("generated code:", resData)

	return resData, nil
}

func ToRoute(routeRequest *RouteRequest,
	arr *ApisixRouteRequest,
	u4 uuid.UUID,
	resp *ApisixRouteResponse) (*Route, *errno.ManagerError) {
	rd := &Route{}
	if err := rd.Parse(routeRequest, arr); err != nil {
		e := errno.FromMessage(errno.DBRouteCreateError, err.Error())
		return nil, e
	}
	if rd.Name == "" {
		rd.Name = routeRequest.Name
	}
	rd.ID = u4
	// content_admin_api
	if resp != nil {
		resp.Node.Value.RouteGroupId = rd.RouteGroupId
		resp.Node.Value.Status = rd.Status
		if respStr, err := json.Marshal(resp); err != nil {
			e := errno.FromMessage(errno.DBRouteCreateError, err.Error())
			return nil, e
		} else {
			rd.ContentAdminApi = string(respStr)
		}
	}
	// hosts
	hosts := routeRequest.Hosts
	if hb, err := json.Marshal(hosts); err != nil {
		e := errno.FromMessage(errno.DBRouteCreateError, err.Error())
		logger.Warn(e.Msg)
	} else {
		rd.Hosts = string(hb)
	}
	// uris
	uris := routeRequest.Uris
	if ub, err := json.Marshal(uris); err != nil {
		e := errno.FromMessage(errno.DBRouteCreateError, err.Error())
		logger.Warn(e.Msg)
	} else {
		rd.Uris = string(ub)
	}
	// upstreamNodes
	if routeRequest.Upstream != nil {
		nodes := routeRequest.Upstream.Nodes
		ips := make([]string, 0)
		for k, _ := range nodes {
			ips = append(ips, k)
		}
		if nb, err := json.Marshal(ips); err != nil {
			e := errno.FromMessage(errno.DBRouteCreateError, err.Error())
			logger.Warn(e.Msg)
		} else {
			rd.UpstreamNodes = string(nb)
		}
	}
	// upstreamId
	rd.UpstreamId = arr.UpstreamId
	return rd, nil
}
