package main

import "log"
import "encoding/json"
import "strings"

//abstract CRUD operation for espoCRM Entity
var crmSite = "https://c.hitxy.org.au/"

func crmCreateEntity(entityType string, jsonB []byte) (entity interface{}, err error) {
	url := crmSite + "api/v1/" + entityType
	jsonStr, err := postRAW(jsonB, url, crmBuildCommonAPIHeader())
	if err != nil {
		entity, _ = crmRescueDuplicateCreate(err, entityType)
		return
	}
	return crmJSON2Entity(entityType, jsonStr)
}

func crmUpdateEntity(entityType string, id string, jsonB []byte) (entity interface{}, err error) {
	url := crmSite + "api/v1/" + entityType + "/" + id
	jsonStr, err := patchRAW(jsonB, url, crmBuildCommonAPIHeader())
	if err != nil {
		log.Println(err)
		return
	}
	return crmJSON2Entity(entityType, jsonStr)
}

func crmReplaceEntity(entityType string, id string, jsonB []byte) (entity interface{}, err error) {
	url := crmSite + "api/v1/" + entityType + "/" + id
	jsonStr, err := putRAW(jsonB, url, crmBuildCommonAPIHeader())
	if err != nil {
		log.Println(err)
		return
	}
	return crmJSON2Entity(entityType, jsonStr)
}

func crmDeleteEntity(entityType string, id string) (deleted bool, err error) {
	url := crmSite + "api/v1/" + entityType + "/" + id
	resp, err := deleteRAW(url, crmBuildCommonAPIHeader())
	if err != nil {
		log.Println(err)
		return
	}
	deleted = strings.ToLower(resp) == "true"
	return
}

//give an id, return json
func crmGetEntity(entityType string, id string) (entity interface{}, err error) {
	url := crmSite + "api/v1/" + entityType + "/" + id
	jsonStr, err := getRAW(url, crmBuildCommonAPIHeader())
	if err != nil {
		log.Println(err)
		return
	}
	return crmJSON2Entity(entityType, jsonStr)
}

func crmBuildCommonAPIHeader() (headers map[string]string) {
	headers = map[string]string{}
	headers["Authorization"] = crmAuthHeader()
	headers["Accept"] = "application/json"
	headers["Content-Type"] = "application/json"
	return headers
}

//given a json string, convert it to Typed structure
func crmJSON2Entity(entityType string, data string) (r interface{}, err error) {
	switch entityType {
	case "Lead":
		e := crmdLead{}
		err = json.Unmarshal([]byte(data), &e)
		r = e
	case "Account":
		//r = crmdAccount{}
	default:
		log.Fatalf("crmJSON2Entity: Unknown EntityType %s", entityType)
	}

	if err != nil {
		log.Println(err)
	}
	return
}

func crmRescueDuplicateCreate(e error, entityType string) (entity interface{}, success bool) {
	if !isErrIndicateDuplicate(e) {
		return
	}
	entity, err := e.(errorHTTPResponse).XStatusReason().Data2Entity(entityType)
	success = err == nil
	return
}

func isErrIndicateDuplicate(e error) (yes bool) {
	err, isOurError := e.(errorHTTPResponse)
	if !isOurError {
		return
	}
	reason := err.XStatusReason()
	yes = strings.ToLower(reason.Reason) == "duplicate"
	return
}


func searchEntity