package ads_external

import (
	"alpha/adDelivery/helper"
	"alpha/adDelivery/structure"
	"fmt"
	"strconv"
	"strings"
	"time"

	"github.com/elliotchance/phpserialize"
)

func GetId() string {

	return strconv.Itoa(int(time.Now().UnixNano() / int64(time.Millisecond)))
}

func GetDspObj(outputData *structure.OutputData, rid string, zninfo structure.ZoneDetails, znextra AdExchangeZone, buyer_details []ExchangeDetails, pub_details SiteObjects__pub) []DspObjects {

	var dspObjs []DspObjects

	for _, buyer := range buyer_details {

		var dspObj DspObjects
		dspObj.Id = buyer.Exchange_id

		buyer_id, buyer_id_err := outputData.R.Cookie("DSP_COOK" + helper.IntToString(dspObj.Id))

		if buyer.Open_rtb_version == "1" {
			dspObj.Ver = "2.5"
		} else if buyer.Open_rtb_version == "2" {
			dspObj.Ver = "2.5"
		} else if buyer.Open_rtb_version == "3" {
			dspObj.Ver = "2.5"
		} else if buyer.Open_rtb_version == "4" {
			dspObj.Ver = "2.5"
		} else if buyer.Open_rtb_version == "5" {
			dspObj.Ver = "3.0"
		}

		if buyer.Auction_currency == 0 {
			dspObj.Cur = []string{"USD"}
		}
		dspObj.Ping_url = buyer.Ping_url
		dspObj.At = buyer.Auction_type
		dspObj.SeconBidBuffer = zninfo.SeconBidBuffer
		dspObj.Gzip = buyer.Gzip

		if buyer_id_err == nil {
			dspObj.Buyer_id = buyer_id.Value

		}

		dspObj.Source = DspObjects__source{Ts: int(time.Now().UnixNano() / int64(time.Millisecond)), Ds: buyer.Digital_signature}

		var AffAdditional map[interface{}]interface{}
		if zninfo.Comments != "" {
			phpserialize.Unmarshal([]byte(zninfo.Comments), &AffAdditional)
		}

		if AffAdditional["app_type"] != nil {

			if znextra.Site_page != "" || znextra.App_url != "" {
				dspObj.Source.Ext.Schain.Sccomplete = 1
			} else {
				dspObj.Source.Ext.Schain.Sccomplete = 0
			}

			//Currently supply chain version is 1.0
			dspObj.Source.Ext.Schain.Scversion = "1.0"

			if fmt.Sprint(AffAdditional["app_type"]) != "3" {

				dspObj.Source.Ext.Schain.Scnodes.Nodes_asi = AffAdditional["app_url"].(string)
			} else {

				dspObj.Source.Ext.Schain.Scnodes.Nodes_asi = pub_details.Domain
			}
			dspObj.Source.Ext.Schain.Scnodes.Nodes_sid = pub_details.Id

			dspObj.Source.Ext.Schain.Scnodes.Nodes_rid = rid
			//If supply chain version is 1.0, then hp is always 1 else it will be applied with the flow of inventory
			dspObj.Source.Ext.Schain.Scnodes.Nodes_hp = 1
		}

		dspObj.Ext.Ads_txt.Status = 1
		dspObj.Ext.Ads_txt.Auth_id = helper.IntToString(zninfo.Affiliateid * 123)
		dspObj.Ext.Ads_txt.Pub_id = helper.IntToString(zninfo.Affiliateid)

		dspObjs = append(dspObjs, dspObj)

	}

	return dspObjs

}
func GetImpAudObj(zninfo structure.ZoneDetails, znextra AdExchangeZone, deals []DealsDetails, protocal int) []ImpAudioObjects {

	impObj := ImpAudioObjects{}

	impObj.Id = "1"
	impObj.Bidfloor = znextra.Imp_bidfloor

	impObj.Audio = ImpObjects__audio{}

	impObj.Audio.Mimes = []string{"audio/aac", "audio/mp4", "audio/mpeg"}
	impObj.Audio.Minduration = znextra.Vid_min
	impObj.Audio.Maxduration = znextra.Vid_max
	if protocal != 0 {
		impObj.Audio.Protocols = []int{protocal}
	} else {
		impObj.Audio.Protocols = []int{9, 10, 11, 12}
	}
	impObj.Audio.Battr = StringToIntArr(znextra.Vid_battr)
	impObj.Audio.Maxextended = znextra.Vid_maxext
	impObj.Audio.Minbitrate = znextra.Vid_minbit
	impObj.Audio.Maxbitrate = znextra.Vid_maxbit
	impObj.Audio.Delivery = []int{znextra.Vid_del}
	impObj.Audio.Api = StringToIntArr(znextra.Vid_api)
	impObj.Audio.Feed = 1
	impObj.Audio.NVol = 0
	impObj.Audio.Stitched = 0
	impObj.Audio.Startdelay = 0
	//impObj.Audio.MaxSequence = 1

	Companionads := []ImpObjects__audio__companionad{}
	Companionad := ImpObjects__audio__companionad{}

	Companionad.Id = "1"
	Companionad.W = znextra.Vid_comp_width
	Companionad.H = znextra.Vid_comp_height

	Companionads = append(Companionads, Companionad)
	impObj.Audio.Companionad = Companionads
	impObj.Audio.Companiontype = StringToIntArr(znextra.Vid_comptype)

	if (zninfo.Inv_type == 2 || zninfo.Inv_type == 3) && len(deals) > 0 {

		impdeals := []ImpObjects__pmp__deals{}
		for _, deal := range deals {

			impdeal := ImpObjects__pmp__deals{Id: deal.Dealid_token, At: deal.Auction_type, Bidfloor: deal.Floor_price, Wseat: strings.Split(deal.Whitelist, ",")}
			impdeals = append(impdeals, impdeal)
		}

		impObj.Pmp = ImpObjects__pmp{Private_auction: 1, Deals: impdeals}
	}

	var impObjs []ImpAudioObjects
	impObjs = append(impObjs, impObj)

	return impObjs
}
func GetImpImgObj(zninfo structure.ZoneDetails, znextra AdExchangeZone, deals []DealsDetails) []ImpImgObjects {

	impObj := ImpImgObjects{}

	impObj.Id = "1"
	impObj.Bidfloor = znextra.Imp_bidfloor

	var mimes []string

	if zninfo.Delivery == "3" {
		mimes = append(mimes, "text/plain")
		zninfo.Width = 0
		zninfo.Height = 0
	} else {

		mimes = strings.Split(znextra.Ban_mimes, ",")

		//~ mimes = append(mimes,"image/jpg")
		//~ mimes = append(mimes,"image/gif")
		//~ mimes = append(mimes,"image/png")
		//~ mimes = append(mimes,"image/jpeg")
		//~ mimes = append(mimes,"text/html")
	}

	impObj.Banner = ImpObjects__banner{W: zninfo.Width, H: zninfo.Height, Pos: 0, Mimes: mimes}

	if (zninfo.Inv_type == 2 || zninfo.Inv_type == 3) && len(deals) > 0 {

		impdeals := []ImpObjects__pmp__deals{}
		for _, deal := range deals {

			impdeal := ImpObjects__pmp__deals{Id: deal.Dealid_token, At: deal.Auction_type, Bidfloor: deal.Floor_price, Wseat: strings.Split(deal.Whitelist, ",")}
			impdeals = append(impdeals, impdeal)
		}

		impObj.Pmp = ImpObjects__pmp{Private_auction: 1, Deals: impdeals}

	}

	var impObjs []ImpImgObjects
	impObjs = append(impObjs, impObj)

	return impObjs

}

func GetImpVidObj(zninfo structure.ZoneDetails, znextra AdExchangeZone, deals []DealsDetails, protocal int) []ImpVideoObjects {

	impObj := ImpVideoObjects{}

	impObj.Id = "1"

	var linearity int

	if zninfo.Delivery == "6" {

		linearity = 1

	} else if zninfo.Delivery == "7" {

		linearity = 2
	}

	impObj.Bidfloor = znextra.Imp_bidfloor

	impObj.Video = ImpObjects__video{}

	impObj.Video.W = znextra.Vid_width
	impObj.Video.H = znextra.Vid_height
	impObj.Video.Pos = znextra.Vid_pos
	//~ impObj.Video.Startdelay = znextra.Startdelay
	impObj.Video.Minduration = znextra.Vid_min
	impObj.Video.Maxduration = znextra.Vid_max
	impObj.Video.Maxextended = znextra.Vid_maxext
	impObj.Video.Minbitrate = znextra.Vid_minbit
	impObj.Video.Maxbitrate = znextra.Vid_maxbit
	impObj.Video.Api = StringToIntArr(znextra.Vid_api)
	if protocal != 0 {
		impObj.Video.Protocols = []int{protocal}
	} else {
		impObj.Video.Protocols = []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12}
	}
	impObj.Video.Mimes = strings.Split(znextra.Vid_mimes, ",")
	impObj.Video.Linearity = linearity
	impObj.Video.Boxingallowed = znextra.Vid_box
	impObj.Video.Playbackmethod = StringToIntArr(znextra.Vid_play)
	impObj.Video.Delivery = []int{znextra.Vid_del}
	impObj.Video.Battr = StringToIntArr(znextra.Vid_battr)

	Companionads := []ImpObjects__video__companionad{}
	Companionad := ImpObjects__video__companionad{}

	Companionad.Id = "1"
	Companionad.W = znextra.Vid_comp_width
	Companionad.H = znextra.Vid_comp_height

	Companionads = append(Companionads, Companionad)
	impObj.Video.Companionad = Companionads
	impObj.Video.Companiontype = StringToIntArr(znextra.Vid_comptype)

	if (zninfo.Inv_type == 2 || zninfo.Inv_type == 3) && len(deals) > 0 {

		impdeals := []ImpObjects__pmp__deals{}
		for _, deal := range deals {

			impdeal := ImpObjects__pmp__deals{Id: deal.Dealid_token, At: deal.Auction_type, Bidfloor: deal.Floor_price, Wseat: strings.Split(deal.Whitelist, ",")}
			impdeals = append(impdeals, impdeal)
		}

		impObj.Pmp = ImpObjects__pmp{Private_auction: 1, Deals: impdeals}

	}

	var impObjs []ImpVideoObjects
	impObjs = append(impObjs, impObj)

	return impObjs

}

func GetSiteObj(zninfo structure.ZoneDetails, znextra AdExchangeZone, glob structure.GlobalVariables) SiteObjects {

	siteObj := SiteObjects{}
	siteObj.Id = strconv.Itoa(zninfo.Zoneid)

	siteObj.Name = glob.DomainName
	siteObj.Domain = znextra.Pub_domain
	siteObj.Page = glob.PageURL
	siteObj.Pagecat = strings.Split(znextra.Site_page, ",")

	siteObj.Inventory.Cat = strings.Split(znextra.Site_cat, ",")
	siteObj.Inventory.SectionCat = strings.Split(znextra.Site_section, ",")
	siteObj.Inventory.PageCat = strings.Split(znextra.Site_page, ",")
	siteObj.Inventory.PrivacyPolicy = znextra.Site_privacy
	siteObj.Inventory.Keywords = znextra.Site_key

	siteObj.Inventory.Publisher.Cat = strings.Split(znextra.Pub_cat, ",")
	siteObj.Inventory.Publisher.Domain = znextra.Pub_domain

	return siteObj

}

func GetAppObj(zninfo structure.ZoneDetails, znextra AdExchangeZone, glob structure.GlobalVariables) AppObject {

	appObj := AppObject{}

	var AffAdditional map[interface{}]interface{}
	if zninfo.Comments != "" {
		phpserialize.Unmarshal([]byte(zninfo.Comments), &AffAdditional)
	}

	appObj.Bundle = AffAdditional["bundle_id"].(string)
	appObj.StoreURL = AffAdditional["app_url"].(string)
	appObj.Paid = helper.StringToInt(AffAdditional["app_version"].(string))

	appObj.Inventory.Cat = strings.Split(znextra.Site_cat, ",")
	appObj.Inventory.SectionCat = strings.Split(znextra.Site_section, ",")
	appObj.Inventory.PageCat = strings.Split(znextra.Site_page, ",")
	appObj.Inventory.PrivacyPolicy = znextra.Site_privacy
	appObj.Inventory.Keywords = znextra.Site_key

	appObj.Inventory.Publisher.Cat = strings.Split(znextra.Pub_cat, ",")
	appObj.Inventory.Publisher.Domain = znextra.Pub_domain
	return appObj

}

func GetRestriObj(zninfo structure.ZoneDetails, znextra AdExchangeZone, glob structure.GlobalVariables) Restrictions {

	restriObj := Restrictions{}

	restriObj.Test = znextra.Req_test
	restriObj.Badv = strings.Split(znextra.Req_badv, ",")
	restriObj.Bapp = strings.Split(znextra.Req_bapp, ",")
	restriObj.Bcat = strings.Split(znextra.Req_bcat, ",")
	restriObj.Secure = znextra.Imp_secure

	return restriObj

}

func GetDeviceObj(zninfo structure.ZoneDetails, znextra AdExchangeZone, glob structure.GlobalVariables) DeviceObjects {

	deviceObj := DeviceObjects{}

	if znextra.Dev_dnt == 0 {

		deviceObj.Ip = glob.Ip_address
		deviceObj.Ua = glob.Useragent
		deviceObj.Make = glob.DeviceName
		deviceObj.Model = glob.DeviceModel

		switch glob.DeviceType {
		case "Computer":
			deviceObj.Devicetype = 2
		case "Phone":
			deviceObj.Devicetype = 1
		case "Tablet":
			deviceObj.Devicetype = 5
		case "Tv":
			deviceObj.Devicetype = 3
		case "Console":
			deviceObj.Devicetype = 7
		default:
			deviceObj.Devicetype = 2

		}

		deviceObj.Os = glob.Os
		deviceObj.Osv = glob.Osv

	}
	return deviceObj

}

func GetGeoObj(zninfo structure.ZoneDetails, znextra AdExchangeZone, glob structure.GlobalVariables) DeviceObjects__geo {

	geoObj := DeviceObjects__geo{}

	geoObj.Type = 1
	geoObj.Lat, _ = strconv.ParseFloat(glob.Latitude, 64)
	geoObj.Lon, _ = strconv.ParseFloat(glob.Longitude, 64)

	geoObj.Country = glob.Country_code

	return geoObj

}

func GetUserObj(zninfo structure.ZoneDetails, znextra AdExchangeZone, glob structure.GlobalVariables) UserObjects {

	userObj := UserObjects{}

	if znextra.User_yob > 0 {
		userObj.Yob = znextra.User_yob
	}

	if znextra.User_gender != "" {
		userObj.Gender = znextra.User_gender
	}

	if znextra.User_gender != "" {
		userObj.Gender = znextra.User_gender
	}

	var userObjects__data []UserObjects__data
	var userObjects__d UserObjects__data

	var segments []Segments
	var segment Segments
	segment.Id = "1"
	segment.Id = znextra.Seg_name
	segment.Id = znextra.Seg_value
	segments = append(segments, segment)
	userObjects__d.Segment = segments

	userObjects__data = append(userObjects__data, userObjects__d)
	userObj.Data = userObjects__data

	return userObj

}

func GetRegObj(zninfo structure.ZoneDetails, znextra AdExchangeZone, glob structure.GlobalVariables) RegsObjects {

	regsObj := RegsObjects{}

	regsObj.Coppa = 1
	regsObj.Gdpr = znextra.Gdpr
	regsObj.Ccpa = znextra.Ccpa

	return regsObj

}

func StringToIntArr(A string) []int {
	a := strings.Split(A, ",")
	var b []int
	for _, v := range a {
		vv, _ := strconv.Atoi(v)
		b = append(b, vv)
	}
	return b
}

func GetVideoNativeObj(zninfo structure.ZoneDetails, znextra AdExchangeZone, deals []DealsDetails) []ImpNativeObjects {

	NativeObj := ImpNativeObjects{}

	NativeObj.Id = "1"
	NativeObj.Bidfloor = znextra.Imp_bidfloor

	var native_ob map[interface{}]interface{}
	phpserialize.Unmarshal([]byte(znextra.Native_objects), &native_ob)

	var nat_assets []interface{}

	nat_ad_title := fmt.Sprintf("%v", native_ob["ad_title"])
	nat_ad_title_length, _ := strconv.Atoi(fmt.Sprintf("%v", native_ob["adtitle_length"]))
	nat_ad_desc_length, _ := strconv.Atoi(fmt.Sprintf("%v", native_ob["desc_length"]))
	nat_ad_data_objects := fmt.Sprintf("%v", native_ob["data_objects"])
	nat_ad_img_types := fmt.Sprintf("%v", native_ob["nativeimgs"])

	if nat_ad_title == "on" {
		native_title_object := Nativeobj_assetsTitle{
			Id:    1,
			Title: Nativeobj_assetsTitle_details{Lens: nat_ad_title_length},
		}
		nat_assets = append(nat_assets, native_title_object)
	}

	nat_ad_img_types_arr := strings.Split(nat_ad_img_types, ",")

	for _, img_types := range nat_ad_img_types_arr {

		if img_types == "icon" {
			native_icon_object := Nativeobj_assetsImg{
				Id:  2,
				Img: Nativeobj_assetsImg_Details{Type: 1},
			}
			nat_assets = append(nat_assets, native_icon_object)

		}

		nv := ImpObjects__video{}

		nv.Pos = znextra.Vid_pos
		nv.Minduration = znextra.Vid_min
		nv.Maxduration = znextra.Vid_max
		nv.Maxextended = znextra.Vid_maxext
		nv.Minbitrate = znextra.Vid_minbit
		nv.Maxbitrate = znextra.Vid_maxbit
		nv.Api = StringToIntArr(znextra.Vid_api)
		nv.Protocols = []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12}
		nv.Mimes = strings.Split(znextra.Vid_mimes, ",")
		nv.Linearity = 1

		native_main_object := Nativeobj_assetsVideo{
			Id:    3,
			Video: nv,
		}

		nat_assets = append(nat_assets, native_main_object)

		// video setup

	}

	default_dataTypes := make(map[string]int)
	default_dataTypes["dj_data_sponsored"] = 1
	default_dataTypes["dj_data_desc"] = 2
	default_dataTypes["dj_data_rating"] = 3
	default_dataTypes["dj_data_likes"] = 4
	default_dataTypes["dj_data_downloads"] = 5
	default_dataTypes["dj_data_price"] = 6
	default_dataTypes["dj_data_salesprice"] = 7
	default_dataTypes["dj_data_phoneno"] = 8
	default_dataTypes["dj_data_address"] = 9
	default_dataTypes["dj_data_desc2"] = 10
	default_dataTypes["dj_data_displayurl"] = 11
	default_dataTypes["dj_data_ctatext"] = 12

	nat_ad_data_types_arr := strings.Split(nat_ad_data_objects, ",")

	for _, data_type := range nat_ad_data_types_arr {

		if data_type == "dj_data_desc" {

			native_data_object := Nativeobj_assetsData{
				Id:   default_dataTypes[data_type] + 3,
				Data: Nativeobj_assetsData_details{Type: default_dataTypes[data_type], Len: nat_ad_desc_length},
			}
			nat_assets = append(nat_assets, native_data_object)

		} else {

			native_data_object := Nativeobj_assetsData{
				Id:   default_dataTypes[data_type] + 3,
				Data: Nativeobj_assetsData_details{Type: default_dataTypes[data_type]},
			}
			nat_assets = append(nat_assets, native_data_object)
		}

	}

	NativeObj.Natives = Nativeobj_details{NativeReq: NativeRequests{Assets: nat_assets}}

	var NativeObjs []ImpNativeObjects
	NativeObjs = append(NativeObjs, NativeObj)

	return NativeObjs

}

func GetImpNativeObj(zninfo structure.ZoneDetails, znextra AdExchangeZone, deals []DealsDetails) []ImpNativeObjects {

	NativeObj := ImpNativeObjects{}

	NativeObj.Id = "1"
	NativeObj.Bidfloor = znextra.Imp_bidfloor

	var native_ob map[interface{}]interface{}
	phpserialize.Unmarshal([]byte(znextra.Native_objects), &native_ob)

	var nat_assets []interface{}

	nat_ad_title := fmt.Sprintf("%v", native_ob["ad_title"])
	nat_ad_title_length, _ := strconv.Atoi(fmt.Sprintf("%v", native_ob["adtitle_length"]))
	nat_ad_desc_length, _ := strconv.Atoi(fmt.Sprintf("%v", native_ob["desc_length"]))
	nat_ad_img_width, _ := strconv.Atoi(fmt.Sprintf("%v", native_ob["img_width"]))
	nat_ad_img_height, _ := strconv.Atoi(fmt.Sprintf("%v", native_ob["img_height"]))
	nat_ad_data_objects := fmt.Sprintf("%v", native_ob["data_objects"])
	nat_ad_img_types := fmt.Sprintf("%v", native_ob["nativeimgs"])

	if nat_ad_title == "on" {
		native_title_object := Nativeobj_assetsTitle{
			Id:    1,
			Title: Nativeobj_assetsTitle_details{Lens: nat_ad_title_length},
		}
		nat_assets = append(nat_assets, native_title_object)
	}

	nat_ad_img_types_arr := strings.Split(nat_ad_img_types, ",")

	for _, img_types := range nat_ad_img_types_arr {

		if img_types == "icon" {
			native_icon_object := Nativeobj_assetsImg{
				Id:  2,
				Img: Nativeobj_assetsImg_Details{Type: 1},
			}
			nat_assets = append(nat_assets, native_icon_object)

		} else if img_types == "main" {

			native_main_object := Nativeobj_assetsImg{
				Id:  3,
				Img: Nativeobj_assetsImg_Details{Type: 3, W: nat_ad_img_width, H: nat_ad_img_height},
			}
			nat_assets = append(nat_assets, native_main_object)
		}

	}

	default_dataTypes := make(map[string]int)
	default_dataTypes["dj_data_sponsored"] = 1
	default_dataTypes["dj_data_desc"] = 2
	default_dataTypes["dj_data_rating"] = 3
	default_dataTypes["dj_data_likes"] = 4
	default_dataTypes["dj_data_downloads"] = 5
	default_dataTypes["dj_data_price"] = 6
	default_dataTypes["dj_data_salesprice"] = 7
	default_dataTypes["dj_data_phoneno"] = 8
	default_dataTypes["dj_data_address"] = 9
	default_dataTypes["dj_data_desc2"] = 10
	default_dataTypes["dj_data_displayurl"] = 11
	default_dataTypes["dj_data_ctatext"] = 12

	nat_ad_data_types_arr := strings.Split(nat_ad_data_objects, ",")

	for _, data_type := range nat_ad_data_types_arr {

		if data_type == "dj_data_desc" {

			native_data_object := Nativeobj_assetsData{
				Id:   default_dataTypes[data_type] + 3,
				Data: Nativeobj_assetsData_details{Type: default_dataTypes[data_type], Len: nat_ad_desc_length},
			}
			nat_assets = append(nat_assets, native_data_object)

		} else {

			native_data_object := Nativeobj_assetsData{
				Id:   default_dataTypes[data_type] + 3,
				Data: Nativeobj_assetsData_details{Type: default_dataTypes[data_type]},
			}
			nat_assets = append(nat_assets, native_data_object)
		}

	}

	NativeObj.Natives = Nativeobj_details{NativeReq: NativeRequests{Assets: nat_assets}}
	fmt.Println(nat_assets)

	var NativeObjs []ImpNativeObjects
	NativeObjs = append(NativeObjs, NativeObj)

	return NativeObjs

}
