package main

import (
	"log"
	"strings"

	"gopkg.in/yaml.v2"
)

type SearchEngine struct {
	Name  string   `yaml:"name"`
	Items []SeItem `yaml:"items"`
}
type SeItem struct {
	Urls           []string `yaml:"urls"`
	QueryParams    []string `yaml:"params"`
	Hiddenkeywords []string `yaml:"hiddenkeyword"`
}

var seData *[]SearchEngine

func init() {
	seData = &[]SearchEngine{}
	err := yaml.Unmarshal(SearchEnginesDefinitionYaml, seData)
	if err != nil {
		log.Fatal(err)
	}

}
func searchEngine(hit map[string]string, URL *UrlParams) {
	hit["SearchEngine"] = ""
	hit["SearchPhrase"] = ""

	if hit["Referer"] == "" {
		return
	}
	host := URL.Host
	host = strings.TrimPrefix(host, "www.")
	host = strings.TrimPrefix(host, "m.")

	// сначала ищем прямое вхождение домена
	seName, queryParams, _ := searchSearchEngine(host)
	if seName == "" {
		// затем заменяем TLD на {}
		host = prepareSearchEngineHost(host)
		seName, queryParams, _ = searchSearchEngine(host)
	}
	hit["SearchEngine"] = seName
	hit["SearchPhrase"] = getQueryParamValue(queryParams, URL.QueryMap)

	utmEngine := hit["UTMSource"]
	if utmEngine != "" {
		switch utmEngine {
		case "yandex":
			hit["SearchEngine"] = "Yandex"
		case "google":
			hit["SearchEngine"] = "Google"
		case "go.mail.ru":
			hit["SearchEngine"] = "Mailru"
		}
	}
}

func searchSearchEngine(host string) (seName string, queryParams, hiddenkeywords []string) {
	for _, se := range *seData {
		for _, item := range se.Items {
			for _, url := range item.Urls {
				if url == host {
					seName = se.Name
					queryParams = item.QueryParams
					hiddenkeywords = item.Hiddenkeywords
					return
				}
			}
		}
	}
	return
}

func getQueryParamValue(queryParams []string, queryMap map[string]string) string {
	for _, qp := range queryParams {
		val, ok := queryMap[qp]
		if ok {
			return val
		}
	}
	return ""
}

func prepareSearchEngineHost(host string) string {
	parts := strings.Split(host, ".")
	if len(parts) < 2 {
		return host
	}

	for _, code := range SearchEngineTLD {
		if parts[0] == code {
			parts[0] = "{}"
			return strings.Join(parts, ".")
		}
	}
	// для домена второго уровня берем 2 части
	lastPart := strings.Join(parts[len(parts)-2:], ".")
	for _, code := range SearchEngineSLD {
		if lastPart == code {
			parts[len(parts)-2] = "{}"
			return strings.Join(parts[:len(parts)-1], ".")
		}
	}

	lastPart = parts[len(parts)-1]
	for _, code := range SearchEngineTLD {
		if lastPart == code {
			parts[len(parts)-1] = "{}"
			return strings.Join(parts, ".")
		}
	}
	return host
}
