package request30

import (
	"ssp/customapi"

	"openrtb/openrtb3"
)
import "encoding/json"


// Function for forming the common objects in v2.5
func FormCommonObjects(channel chan *openrtb3.Request, req *customapi.CustomRequest) {
	bidRequest := &openrtb3.Request{}
	bidRequest.ID = req.ID
	var context openrtb3.Context
	// Item Object
	bidRequest.Item = make([]openrtb3.Item, len(req.Imp))
	for k, v := range req.Imp {
		var (
			display   openrtb3.Display
			spec      openrtb3.Spec
			placement openrtb3.Placement
		)
		bidRequest.Item[k].ID = v.ID
		bidRequest.Item[k].Flr = v.BidFloor
		
		placement.Secure = req.Restrictions.Secure 
	
		bidRequest.Item[k].Metric = make([]openrtb3.Metric, len(v.Metric))
		for k1, v1 := range v.Metric {
			bidRequest.Item[k].Metric[k1].Type = v1.Type
			bidRequest.Item[k].Metric[k1].Value = v1.Value
			bidRequest.Item[k].Metric[k1].Vendor = v1.Vendor
			bidRequest.Item[k].Metric[k1].Ext = v1.Ext
		}

		// Banner Object
		if v.Banner != nil {
			var (
				displayfmt []*openrtb3.Displayfmt
				dfmt       openrtb3.Displayfmt
			)
			displayfmt = make([]*openrtb3.Displayfmt, 1)
			display.Mimes = v.Banner.Mimes
			dfmt.W = v.Banner.W
			dfmt.H = v.Banner.H
			displayfmt[k] = &dfmt
			display.Displayfmt = displayfmt
			placement.Display = &display
			spec.Placement = &placement
			bidRequest.Item[k].Spec = &spec
		}


		
		// Video Object
		if v.Video != nil {
			var vid openrtb3.Video
			vid.Mime = v.Video.Mimes
			vid.Mindur = v.Video.MinDuration
			vid.Maxdur = v.Video.MaxDuration
			vid.Ctype = v.Video.Protocols
			vid.W = v.Video.W
			vid.H = v.Video.H
			vid.Delay = v.Video.StartDelay
			vid.Linear = v.Video.Linearity
			vid.Skip = v.Video.Skip
			vid.Skipmin = v.Video.SkipMin
			vid.Skipafter = v.Video.SkipAfter
			vid.MaxExtended = v.Video.MaxExtended
			vid.Minbitr = v.Video.MinBitrate
			vid.Maxbitr = v.Video.MaxBitrate
			vid.Boxing = *v.Video.BoxingAllowed
			vid.Playmethod = v.Video.PlaybackMethod
			vid.Delivery = v.Video.Delivery
			vid.Pos = v.Video.Pos
			if len(v.Video.CompanionAd) > 0 {
				var (
					comp []*openrtb3.Comp
				)
				comp = make([]*openrtb3.Comp, len(v.Video.CompanionAd))
				for k1, v1 := range v.Video.CompanionAd {
					var (
						c          openrtb3.Comp
						displayfmt []*openrtb3.Displayfmt
						dfmt       openrtb3.Displayfmt
						display1   openrtb3.Display
					)
					displayfmt = make([]*openrtb3.Displayfmt, 1)
					display1.Mimes = v1.Mimes
					dfmt.W = v1.W
					dfmt.H = v1.H
					displayfmt[0] = &dfmt
					display1.Displayfmt = displayfmt
					c.Display = &display1
					comp[k1] = &c
				}
				vid.Comp = comp
			}
			vid.Api = v.Video.Api
			vid.Comptype = v.Video.CompanionType
			vid.Ptype = v.Video.Placement

			placement.Video = &vid
			spec.Placement = &placement
			bidRequest.Item[k].Spec = &spec
		}

		// Audio Object
		if v.Audio != nil {
			var aud openrtb3.Audio
			aud.Mime = v.Audio.Mimes
			aud.Mindur = v.Audio.MinDuration
			aud.Maxdur = v.Audio.MaxDuration
			aud.Ctype = v.Audio.Protocols
			aud.Delay = v.Audio.StartDelay
			aud.MaxExtended = v.Audio.MaxExtended
			aud.Minbitr = v.Audio.MinBitrate
			aud.Maxbitr = v.Audio.MaxBitrate
			aud.Delivery = v.Audio.Delivery
			if len(v.Audio.CompanionAd) > 0 {
				var (
					comp []*openrtb3.Comp
				)
				comp = make([]*openrtb3.Comp, len(v.Audio.CompanionAd))
				for k1, v1 := range v.Audio.CompanionAd {
					var (
						c          openrtb3.Comp
						displayfmt []*openrtb3.Displayfmt
						dfmt       openrtb3.Displayfmt
						display1   openrtb3.Display
					)
					displayfmt = make([]*openrtb3.Displayfmt, 1)
					display1.Mimes = v1.Mimes
					dfmt.W = v1.W
					dfmt.H = v1.H
					displayfmt[0] = &dfmt
					display1.Displayfmt = displayfmt
					c.Display = &display1
					comp[k1] = &c
				}
				aud.Comp = comp
			}
			aud.Comptype = v.Audio.CompanionType
			aud.Maxseq = v.Audio.MaxSequence
			aud.Api = v.Audio.API
			aud.Feed = v.Audio.Feed
			aud.Nvol = v.Audio.NVol

			placement.Audio = &aud
			spec.Placement = &placement
			bidRequest.Item[k].Spec = &spec
		}

		// Native Object
		if v.Native != nil {
			var nativefmt openrtb3.Nativefmt

			if len(v.Native.Request.Asset) > 0 {
				var ass []*openrtb3.Asset
				ass = make([]*openrtb3.Asset, len(v.Native.Request.Asset))
				for k1, v1 := range v.Native.Request.Asset {
					if v1 != nil {
						var ast openrtb3.Asset
						ast.Id = v1.Id
						ast.Req = v1.Req
						if v1.Title != nil {
							var astTitle openrtb3.Title
							astTitle.Len = v1.Title.Len
							ast.Title = &astTitle
						}

						if v1.Img != nil {
							var astImg openrtb3.Img
							astImg.Type = v1.Img.Type
							astImg.W = v1.Img.W
							astImg.Wmin = v1.Img.Wmin
							astImg.H = v1.Img.H
							astImg.Hmin = v1.Img.Hmin
							astImg.Mime = v1.Img.Mime
							ast.Img = &astImg
						}

						if v1.Data != nil {
							var astData openrtb3.DataN
							astData.Len = v1.Data.Len
							astData.Type = v1.Data.Type
							ast.Data = &astData
						}

						// Video Object
						if v1.Video != nil {
							var vid openrtb3.Video
							vid.Mime = v1.Video.Mimes
							vid.Mindur = v1.Video.MinDuration
							vid.Maxdur = v1.Video.MaxDuration
							vid.Ctype = v1.Video.Protocols
							vid.W = v1.Video.W
							vid.H = v1.Video.H
							vid.Delay = v1.Video.StartDelay
							vid.Linear = v1.Video.Linearity
							vid.Skip = v1.Video.Skip
							vid.Skipmin = v1.Video.SkipMin
							vid.Skipafter = v1.Video.SkipAfter
							vid.MaxExtended = v1.Video.MaxExtended
							vid.Minbitr = v1.Video.MinBitrate
							vid.Maxbitr = v1.Video.MaxBitrate
							//~ vid.Boxing = *v1.Video.BoxingAllowed
							vid.Playmethod = v1.Video.PlaybackMethod
							vid.Delivery = v1.Video.Delivery
							vid.Pos = v1.Video.Pos
							if len(v1.Video.CompanionAd) > 0 {
								var (
									comp []*openrtb3.Comp
								)
								comp = make([]*openrtb3.Comp, len(v1.Video.CompanionAd))
								for k2, v2 := range v1.Video.CompanionAd {
									var (
										c          openrtb3.Comp
										displayfmt []*openrtb3.Displayfmt
										dfmt       openrtb3.Displayfmt
										display1   openrtb3.Display
									)
									displayfmt = make([]*openrtb3.Displayfmt, 1)
									display1.Mimes = v2.Mimes
									dfmt.W = v2.W
									dfmt.H = v2.H
									displayfmt[0] = &dfmt
									display1.Displayfmt = displayfmt
									c.Display = &display1
									comp[k2] = &c
								}
								vid.Comp = comp
							}
							
							
							vid.Api = v1.Video.Api
							vid.Comptype = v1.Video.CompanionType
							vid.Ptype = v1.Video.Placement
							ast.Video = &vid
						}
						
										ass[k1] = &ast


					
					}
				}
								nativefmt.Asset = ass

			}
			
						
						
			display.Nativefmt = &nativefmt
			placement.Display = &display
			spec.Placement = &placement
			bidRequest.Item[k].Spec = &spec
		}

		// PMP Object
		if v.Pmp != nil {
			bidRequest.Item[k].Private = v.Pmp.Private
			if v.Pmp.Private != 0 {
				var deal []openrtb3.Deal
				if len(v.Pmp.Deals) > 0 && v.Pmp.Private != 0 {
					deal = make([]openrtb3.Deal, len(v.Pmp.Deals))
					for k1, v1 := range v.Pmp.Deals {
						deal[k1].ID = v1.ID
						deal[k1].Flr = v1.Flr
					}
				}
				bidRequest.Item[k].Deal = deal
			}
		}
		


	}

	// Site Object
	if req.Site != nil && req.Site.ID !="" {
		var site openrtb3.Site
		var publisher openrtb3.Publisher
		site.ID = req.Site.ID
		site.Name = req.Site.Name
		site.Domain = req.Site.Domain
		site.Cat = req.Site.Cat
		site.SecCat = req.Site.SectionCat
		site.PageCat = req.Site.PageCat
		if req.Site.Publisher != nil {
			publisher.ID = req.Site.Inventory.Publisher.ID
			publisher.Name = req.Site.Inventory.Publisher.Name
			publisher.Cat = req.Site.Inventory.Publisher.Cat
			publisher.Domain = req.Site.Inventory.Publisher.Domain
			publisher.Ext = req.Site.Inventory.Publisher.Ext
			site.Pub = &publisher
		}
		site.Amp = req.Site.Amp
		site.Page = req.Site.Page
		site.RefPage = req.Site.Ref
		site.Mobile = req.Site.Mobile
		context.Site = &site
	}

	// App Object
	if req.App != nil && req.App.Bundle !="" {
		var app openrtb3.App
		var publisher openrtb3.Publisher
		app.Inventory.ID = req.App.ID
		app.Inventory.Name = req.App.Name
		app.Inventory.Domain = req.App.Domain
		app.Inventory.Cat = req.App.Cat
		app.Inventory.SectionCat = req.App.SectionCat
		app.Inventory.PageCat = req.App.PageCat
		app.Inventory.PrivacyPolicy = req.App.PrivacyPolicy
		
		if req.App.Inventory.Publisher != nil {
			publisher.ID = req.App.Inventory.Publisher.ID
			publisher.Name = req.App.Inventory.Publisher.Name
			publisher.Cat = req.App.Inventory.Publisher.Cat
			publisher.Domain = req.App.Inventory.Publisher.Domain
			publisher.Ext = req.App.Inventory.Publisher.Ext
			app.Inventory.Publisher = &publisher
		}
		app.Inventory.Keywords = req.App.Inventory.Keywords
		app.Bundle = req.App.Bundle
		app.StoreURL = req.App.StoreURL
		app.Ver = req.App.Ver
		app.Paid = req.App.Paid
		context.App = &app
	}

	// Device Object
	if req.Device != nil {
		var device openrtb3.Device
		var geo openrtb3.Geo
		device.UA = req.Device.UA
		if req.Device.Geo != nil {
			geo.Lat = req.Device.Geo.Lat
			geo.Lon = req.Device.Geo.Lon
			geo.Type = req.Device.Geo.Type
			geo.Accuracy = req.Device.Geo.Accuracy
			geo.LastFix = req.Device.Geo.LastFix
			geo.IPService = req.Device.Geo.IPService
			geo.Country = req.Device.Geo.Country
			geo.Region = req.Device.Geo.Region
			geo.RegionFIPS104 = req.Device.Geo.RegionFIPS104
			geo.Metro = req.Device.Geo.Metro
			geo.City = req.Device.Geo.City
			geo.Zip = req.Device.Geo.Zip
			geo.UTCOffset = req.Device.Geo.UTCOffset
			geo.Ext = req.Device.Geo.Ext
			device.Geo = &geo
		}
		device.DNT = req.Device.DNT
		device.LMT = req.Device.LMT
		device.IP = req.Device.IP
		device.IPv6 = req.Device.IPv6
		device.DeviceType = req.Device.DeviceType
		device.Make = req.Device.Make
		device.Model = req.Device.Model
		device.OS = req.Device.OS
		device.OSVer = req.Device.OSVer
		device.HwVer = req.Device.HwVer
		device.H = req.Device.H
		device.W = req.Device.W
		device.PPI = req.Device.PPI
		device.PxRatio = req.Device.PxRatio
		device.JS = req.Device.JS
		device.GeoFetch = req.Device.GeoFetch
		device.FlashVer = req.Device.FlashVer
		device.Language = req.Device.Language
		device.Carrier = req.Device.Carrier
		device.MCCMNC = req.Device.MCCMNC
		device.IFA = req.Device.IFA
		device.IDSHA1 = req.Device.IDSHA1
		device.IDMD5 = req.Device.IDMD5
		device.PIDSHA1 = req.Device.PIDSHA1
		device.PIDMD5 = req.Device.PIDMD5
		device.MacSHA1 = req.Device.MacSHA1
		device.MacMD5 = req.Device.MacMD5
		device.Ext = req.Device.Ext
		context.Device = &device
	}

	// User Object
	if req.User != nil {
		var user openrtb3.User
		var geo openrtb3.Geo
		user.ID = req.User.ID
		user.Consent = req.User.Consent
		user.BuyerID = req.User.BuyerID
		user.BuyerUID = req.User.BuyerUID
		user.YOB = req.User.YOB
		user.Gender = req.User.Gender
		user.Keywords = req.User.Keywords
		user.CustomData = req.User.CustomData
		if req.User.Geo != nil {
			geo.Lat = req.User.Geo.Lat
			geo.Lon = req.User.Geo.Lon
			geo.Type = req.User.Geo.Type
			geo.Accuracy = req.User.Geo.Accuracy
			geo.LastFix = req.User.Geo.LastFix
			geo.IPService = req.User.Geo.IPService
			geo.Country = req.User.Geo.Country
			geo.Region = req.User.Geo.Region
			geo.RegionFIPS104 = req.User.Geo.RegionFIPS104
			geo.Metro = req.User.Geo.Metro
			geo.City = req.User.Geo.City
			geo.Zip = req.User.Geo.Zip
			geo.UTCOffset = req.User.Geo.UTCOffset
			geo.Ext = req.User.Geo.Ext
			user.Geo = &geo
		}
		if len(req.User.Data) > 0 {
			user.Data = make([]openrtb3.Data, len(req.User.Data))
			for k, v := range req.User.Data {
				user.Data[k].ID = v.ID
				user.Data[k].Name = v.Name
				if len(v.Segment) > 0 {
					user.Data[k].Segment = make([]openrtb3.Segment, len(v.Segment))
					for k1, v1 := range v.Segment {
						user.Data[k].Segment[k1].ID = v1.ID
						user.Data[k].Segment[k1].Name = v1.Name
						user.Data[k].Segment[k1].Value = v1.Value
						user.Data[k].Segment[k1].Ext = v1.Ext
					}
				}
				user.Data[k].Ext = v.Ext
			}
		}
		user.Ext = req.User.Ext
		context.User = &user
	}

	// Regulations Object
	if req.Regs != nil {
		var regs openrtb3.Regulations
		regs.Coppa = req.Regs.Coppa
		regs.GDPR = req.Regs.Gdpr
		regs.CCPA = req.Regs.Ccpa
		regs.Ext = req.Regs.Ext
		context.Regs = &regs
	}

	// Restrictions Object
	if req.Restrictions != nil {
		var restrict openrtb3.Restrictions
		restrict.Cattax = req.Restrictions.Cattax
		restrict.Badv = req.Restrictions.Badv
		restrict.Bapp = req.Restrictions.Bapp
		restrict.Bcat = req.Restrictions.Bcat
		restrict.Battr = req.Restrictions.Battr
		restrict.Ext = req.Restrictions.Ext
		bidRequest.Test = int8(req.Restrictions.Test)

		context.Restrictions = &restrict
	}

	// Regulations Object
	if req.Dooh != nil {
		var dooh openrtb3.Dooh
		var publisher openrtb3.Publisher
		dooh.ID = req.Dooh.ID
		if req.Dooh.Pub != nil {
			publisher.ID = req.Dooh.Pub.ID
			publisher.Name = req.Dooh.Pub.Name
			publisher.Cat = req.Dooh.Pub.Cat
			publisher.Domain = req.Dooh.Pub.Domain
			publisher.Ext = req.Dooh.Pub.Ext
			dooh.Pub = &publisher
		}
		dooh.Fixed = req.Dooh.Fixed
		dooh.Etime = req.Dooh.Etime
		context.Dooh = &dooh
	}


	bidRequest.Context = context
			if req.Restrictions.Ext != nil {
	req_ext, _ := json.Marshal(req.Restrictions.Ext)
	
	bidRequest.Ext = req_ext 
	
	}

	channel <- bidRequest
}
