package main

import (
	"crypto/tls"
	"database/sql"
	"encoding/base64"
	"encoding/json"
	"encoding/xml"
	"fmt"
	"gocron"
	"gorilla/mux"
	"io/ioutil"
	"log"
	"mongo/bson"
	"net/http"
	"net/url"
	"os"
	"os/exec"
	"ssp/ad"
	"ssp/constants"
	"ssp/customapi"
	"ssp/db"
	"ssp/logger"
	"ssp/mongoClient"
	"ssp/redisClient"
	"ssp/validate"
	"ssp/vastxmlstructs"
	"strconv"
	"strings"
	"time"

	"github.com/mssola/user_agent"
)

var redisclient = redisClient.Initialize()

// Home Function
func home(w http.ResponseWriter, r *http.Request) {

	html := `<html>
				<title>Golang SSP API</title>    
				<body>
					<h1>` + `Golang SSP API` + `</h1>
				</body>
			</html>`
	w.Write([]byte(fmt.Sprintf(html)))
}

func processRedisCron() {

	t := time.Now()

	//~ t = t.Add(time.Duration(-5) * time.Minute)
	y := t.Year()
	mon := int(t.Month())
	d := t.Day()
	h := t.Hour()
	min := GetMinalt(t.Minute())
	tableSuffix := strconv.Itoa(y) + strconv.Itoa(mon) + strconv.Itoa(d) + strconv.Itoa(h) + strconv.Itoa(min)

	mongoClient.MongoRequestMove(tableSuffix)
	mongoClient.MongoResponseMove(tableSuffix)
	mongoClient.MongoWinMove(tableSuffix)

}

// Home Function
func validataion(w http.ResponseWriter, r *http.Request) {
	html := `loaderio-492353c0ec8629e10bc4d816e68b7e76`
	w.Write([]byte(fmt.Sprintf(html)))
}

// Function for calculating request elapsed time
func elapsed(what string) func() {
	start := time.Now()
	return func() {
		log.Printf("%s took %v\n", what, time.Since(start))
	}
}

// Function for processing incoming request
func processRequest(w http.ResponseWriter, r *http.Request) {

	ResponseArray := make(map[string]interface{})
	RequestArray := &customapi.CustomRequest{}

	// create header
	w.Header().Add("Content-Type", "application/json")

	err := json.NewDecoder(r.Body).Decode(&RequestArray)

	if err != nil {
		ResponseArray["message"] = "Request Error"
		w.WriteHeader(http.StatusBadRequest)
		json.NewEncoder(w).Encode(ResponseArray)
		return
	}

	//~ mongoClient.MongoSaveDummyData()

	ResponseArray, err = getAD(RequestArray)

	//~ return

	if err != nil {
		ResponseArray["message"] = err.Error()
		w.WriteHeader(http.StatusBadRequest)
		json.NewEncoder(w).Encode(ResponseArray)
		return
	} else {
		w.WriteHeader(http.StatusOK)
		json.NewEncoder(w).Encode(ResponseArray)
		return
	}
}

// Function for getting AD
func getAD(RequestArray *customapi.CustomRequest) (map[string]interface{}, error) {
	Channel := make(chan map[string]interface{})
	ResponseArray := make(map[string]interface{})
	ErrorArray := validate.ValidateRequest(RequestArray)

	if len(ErrorArray) == 0 {
		go ad.Ssp_adprocessing(Channel, RequestArray, redisclient)
		ResponseArray = <-Channel
		return ResponseArray, nil
	} else {
		return ResponseArray, ErrorArray[0]
	}
}

// Function for processing Win Notice request
func processWinnotice(w http.ResponseWriter, r *http.Request) {
	//~ id := r.URL.Query().Get("id")
	//~ bidderid := r.URL.Query().Get("bidderid")

	nurl, err := base64.StdEncoding.DecodeString(r.URL.Query().Get("nurl"))
	if err != nil {
		logger.Log.Println("Error : ", err.Error())
		return
	}
	// Make a cURL get request
	resp, err := http.Get(string(nurl))

	// Log error when request not successful
	if err != nil {
		logger.Log.Println("Error : ", err.Error())
		return
	}

	// Close response body
	defer resp.Body.Close()
}

// Function for processing Win Notice request
func processBillingnotice(w http.ResponseWriter, r *http.Request) {

	id := r.URL.Query().Get("id")
	//~ bidderid := r.URL.Query().Get("bidderid")

	mongoClient.MongoSaveWinAction(id)

	burl, err := base64.StdEncoding.DecodeString(r.URL.Query().Get("burl"))
	if err != nil {
		logger.Log.Println("Error : ", err.Error())
		return
	}
	// Make a cURL get request
	resp, err := http.Get(string(burl))

	// Log error when request not successful
	if err != nil {
		logger.Log.Println("Error : ", err.Error())
		return
	}

	// Close response body
	defer resp.Body.Close()

}

// Function for processing Ad Click request
func processImpUrl(w http.ResponseWriter, r *http.Request) {
	ProcessDetails := make(map[string]interface{})
	ProcessDetails["zoneid"] = r.URL.Query().Get("zoneid")
	ProcessDetails["bannerid"] = r.URL.Query().Get("bannerid")
	ProcessDetails["campaignid"] = r.URL.Query().Get("campaignid")

}

// Function for processing Loss Notice request
func processLossnotice(w http.ResponseWriter, r *http.Request) {
	id := r.URL.Query().Get("id")
	bidderid := r.URL.Query().Get("bidderid")
	log.Println("loss", id)
	log.Println("loss", bidderid)
	lurl, err := base64.StdEncoding.DecodeString(r.URL.Query().Get("lurl"))
	if err != nil {
		logger.Log.Println("Error : ", err.Error())
		return
	}
	// Make a cURL get request
	resp, err := http.Get(string(lurl))

	// Log error when request not successful
	if err != nil {
		logger.Log.Println("Error : ", err.Error())
		return
	}

	// Close response body
	defer resp.Body.Close()
}

// Function for processing Loss Notice request
func processVastWrapper(w http.ResponseWriter, r *http.Request) {
	var (
		x   []byte
		err error
	)
	xmlS := &vastxmlstructs.VastTypes{}
	key := r.URL.Query().Get("key")
	fmt.Println("key", key)
	err = redisclient.GetKey(key, xmlS)

	if xmlS.VAST2 != nil {
		x, err = xml.MarshalIndent(xmlS.VAST2, "", "  ")
		if err != nil {
			http.Error(w, err.Error(), http.StatusInternalServerError)
			return
		}
	} else if xmlS.WVAST2 != nil {
		x, err = xml.MarshalIndent(xmlS.WVAST2, "", "  ")
		if err != nil {
			http.Error(w, err.Error(), http.StatusInternalServerError)
			return
		}
	} else if xmlS.VAST3 != nil {
		x, err = xml.MarshalIndent(xmlS.VAST3, "", "  ")
		if err != nil {
			http.Error(w, err.Error(), http.StatusInternalServerError)
			return
		}
	} else if xmlS.WVAST3 != nil {
		x, err = xml.MarshalIndent(xmlS.WVAST3, "", "  ")
		if err != nil {
			http.Error(w, err.Error(), http.StatusInternalServerError)
			return
		}
	} else if xmlS.VAST4 != nil {
		x, err = xml.MarshalIndent(xmlS.VAST4, "", "  ")
		if err != nil {
			http.Error(w, err.Error(), http.StatusInternalServerError)
			return
		}
	} else if xmlS.WVAST4 != nil {
		x, err = xml.MarshalIndent(xmlS.WVAST4, "", "  ")
		if err != nil {
			http.Error(w, err.Error(), http.StatusInternalServerError)
			return
		}
	} else if xmlS.VAST41 != nil {
		x, err = xml.MarshalIndent(xmlS.VAST41, "", "  ")
		if err != nil {
			http.Error(w, err.Error(), http.StatusInternalServerError)
			return
		}
	} else if xmlS.WVAST41 != nil {
		x, err = xml.MarshalIndent(xmlS.WVAST41, "", "  ")
		if err != nil {
			http.Error(w, err.Error(), http.StatusInternalServerError)
			return
		}
	}
	if err != nil {
		logger.Log.Println("Key : "+key+" expired or error in getting redis key: ", err.Error())
		http.Error(w, "Not Found", http.StatusNotFound)
		return
	}

	allowedHeaders := "Accept, Content-Type, Content-Length, Accept-Encoding, Authorization,X-CSRF-Token"
	w.Header().Set("Access-Control-Allow-Origin", "*")
	u, _ := url.Parse(r.Header.Get("Referer"))
	w.Header().Set("Content-Type", "text/xml; charset=utf-8")
	w.Header().Set("Access-Control-Allow-Origin", u.Scheme+"://"+u.Host)
	w.Header().Set("Access-Control-Allow-Credentials", "true")
	w.Header().Set("Access-Control-Allow-Methods", "POST, GET, OPTIONS, PUT, DELETE")
	w.Header().Set("Access-Control-Allow-Headers", allowedHeaders)
	w.Header().Set("Access-Control-Expose-Headers", "Authorization")
	w.Write(x)
}

func VastWrapper(w http.ResponseWriter, r *http.Request) {

	key := r.URL.Query().Get("overlaykey")
	allowedHeaders := "Accept, Content-Type, Content-Length, Accept-Encoding, Authorization,X-CSRF-Token"
	w.Header().Set("Access-Control-Allow-Origin", "*")
	u, _ := url.Parse(r.Header.Get("Referer"))
	w.Header().Set("Content-Type", "text/xml; charset=utf-8")
	w.Header().Set("Access-Control-Allow-Origin", u.Scheme+"://"+u.Host)
	w.Header().Set("Access-Control-Allow-Credentials", "true")
	w.Header().Set("Access-Control-Allow-Methods", "POST, GET, OPTIONS, PUT, DELETE")
	w.Header().Set("Access-Control-Allow-Headers", allowedHeaders)
	w.Header().Set("Access-Control-Expose-Headers", "Authorization")

	var (
		err error
	)
	var xmlS string
	err = redisclient.GetKey(key, &xmlS)

	if err != nil {
		http.Error(w, "Not Found", http.StatusNotFound)
		return
	}

	w.Write([]byte(xmlS))
}

func GetMin(k int) (m int) {
	if k <= 15 && k >= 0 {
		m = 0
	} else if k <= 30 && k > 15 {
		m = 15
	} else if k <= 45 && k > 30 {
		m = 30
	} else if k <= 59 && k > 45 {
		m = 45
	}
	return
}

// Function for getting minutes
func GetMinalt(k int) (m int) {

	if k%5 > 0 {
		m = k - (k % 5)

	}

	return

}

// Function for processing Mongo to Mysql Cron
func processSspMongoCron() {
	fmt.Println("mongo cron started")
	var migration_table = constants.TablePrefix + "dj_ssp_advanced_reports_bkt"

	defer func() {
		if err := recover(); err != nil {
			logger.Log.Println("Error occured :", err, "Recovered from panic")
		}
	}()

	type ReqRes struct {
		BidderID    int32  `json:"bidderid" bson:"bidderid"`
		Zone_id     string `json:"zone_id" bson:"zone_id"`
		Banner_type int32  `json:"banner_type" bson:"banner_type"`
		Ua          string `json:"ua" bson:"ua"`
		Device_type int32  `json:"device_type" bson:"device_type"`
		Country     string `json:"country" bson:"country"`
		Ip          string `json:"ip" bson:"ip"`
		Os          string `json:"os" bson:"os"`
		Make        string `json:"make" bson:"make"`
		Model       string `json:"model" bson:"model"`
		Language    string `json:"language" bson:"language"`
		Domain      string `json:"domain" bson:"domain"`
		Gender      string `json:"gender" bson:"gender"`
		Yob         int    `json:"yob" bson:"yob"`
		Page        string `json:"page" bson:"page"`
		Ref         string `json:"ref" bson:"ref"`
		Currency    string `json:"currency" bson:"currency"`
		//~ Datetime  string `json:"datetime" bson:"datetime"`
	}

	// Migration Request struct
	type ReqMigration struct {
		Request       ReqRes `json:"_id" bson:"_id"`
		Request_count int    `json:"request_count" bson:"request_count"`
	}

	// Migration Response struct
	type ResMigration struct {
		Response            ReqRes  `json:"_id" bson:"_id"`
		Response_count      int     `json:"response_count" bson:"response_count"`
		Winnotice_count     int     `json:"winnotice_count" bson:"winnotice_count"`
		TestWinnotice_count int     `json:"testwinnotice_count" bson:"testwinnotice_count"`
		Adminshare_count    float64 `json:"adminshare_count" bson:"adminshare_count"`
		Price_count         float64 `json:"price_count" bson:"price_count"`
		Click_count         int     `json:"clickcount" bson:"clickcount"`
		Impression_count    int     `json:"impressioncount" bson:"impressioncount"`
	}

	t := time.Now()
	yC := t.Year()
	monC := AddZeros(int(t.Month()))
	dC := AddZeros(t.Day())
	hC := AddZeros(t.Hour())
	minC := AddZeros(mongoClient.GetMin(t.Minute()))
	layout := "2006-01-02 15:04:00"
	str := strconv.Itoa(yC) + "-" + monC + "-" + dC + " " + hC + ":" + minC + ":00"
	t, _ = time.Parse(layout, str)
	logger.Log.Println("Mongo to MYSQL Migration started at " + time.Now().Format("2006-01-02 15:04:05"))

	to := t.Add(time.Duration(-60) * time.Minute)
	y := to.Year()
	mon := int(to.Month())
	d := to.Day()
	h := to.Hour()
	min := GetMin(to.Minute())
	tableSuffix := strconv.Itoa(y) + strconv.Itoa(mon) + strconv.Itoa(d) + strconv.Itoa(h) + strconv.Itoa(min)
	//~ tableSuffix = "2021120715"

	datetime := strconv.Itoa(y) + "-" + strconv.Itoa(mon) + "-" + strconv.Itoa(d) + " " + strconv.Itoa(h) + ":" + strconv.Itoa(min) + ":00"
	log.Println(datetime)
	// Get a handle for mongo request collection
	logger.Log.Println("Request Collection : " + constants.MongoRequestTable + "_" + tableSuffix)
	clientReq, collectionReq := mongoClient.MongoCollection(constants.MongoRequestTable + "_" + tableSuffix)
	// clientReq, collectionReq := mongoClient.MongoCollection(constants.MongoRequestTable + "_2024122615")
	if collectionReq == nil {
		logger.Log.Println("Error occured ")
		return
	}

	defer clientReq.Close()

	// Get a handle for mongo response collection
	logger.Log.Println("Response Collection : " + constants.MongoResponseTable + "_" + tableSuffix)
	clientRes, collectionRes := mongoClient.MongoCollection(constants.MongoResponseTable + "_" + tableSuffix)
	// clientRes, collectionRes := mongoClient.MongoCollection(constants.MongoResponseTable + "_20231226745")
	if collectionRes == nil {
		logger.Log.Println("Error occured : ")
		return
	}
	defer clientRes.Close()

	// clientWin, collectionWin := mongoClient.MongoCollection(constants.MongoWinNoticeTable + "_20231226745")
	clientWin, collectionWin := mongoClient.MongoCollection(constants.MongoWinNoticeTable + "_" + tableSuffix)
	if collectionWin == nil {
		logger.Log.Println("Error occured : ")
		return
	}
	defer clientWin.Close()

	reqPipeline := []bson.M{
		{
			"$group": bson.M{
				"_id": bson.M{
					"bidderid":    "$bidderid",
					"banner_type": "$banner_type",
					"zone_id":     "$data.site.id",
					"ua":          "$data.device.ua",
					"device_type": "$data.device.device_type",
					"country":     "$data.device.geo.country",
					"ip":          "$data.device.ip",
					"os":          "$data.device.os",
					"make":        "$data.device.make",
					"model":       "$data.device.model",
					"language":    "$data.device.language",
					"domain":      "$data.site.domain",
					"page":        "$data.site.page",
					"gender":      "$data.user.gender",
					"yob":         "$data.user.yob",
					"currency":    "$data.cur",
				},
				"request_count": bson.M{
					"$sum": 1,
				},
			},
		},
	}

	resPipeline := []bson.M{
		{
			"$group": bson.M{
				"_id": bson.M{
					"bidderid":    "$bidderid",
					"banner_type": "$banner_type",
					"zone_id":     "$data.site.id",
					"ua":          "$data.device.ua",
					"device_type": "$data.device.device_type",
					"country":     "$data.device.geo.country",
					"ip":          "$data.device.ip",
					"os":          "$data.device.os",
					"make":        "$data.device.make",
					"model":       "$data.device.model",
					"language":    "$data.device.language",
					"domain":      "$data.site.domain",
					"page":        "$data.site.page",
					"gender":      "$data.user.gender",
					"yob":         "$data.user.yob",
					"currency":    "$data.cur",
				},
				"response_count": bson.M{
					"$sum": 1,
				},
			},
		},
	}

	winPipeline := []bson.M{
		{
			"$group": bson.M{
				"_id": bson.M{
					"bidderid":    "$bidderid",
					"banner_type": "$banner_type",
					"zone_id":     "$data.site.id",
					"ua":          "$data.device.ua",
					"device_type": "$data.device.device_type",
					"country":     "$data.device.geo.country",
					"ip":          "$data.device.ip",
					"os":          "$data.device.os",
					"make":        "$data.device.make",
					"model":       "$data.device.model",
					"language":    "$data.device.language",
					"domain":      "$data.site.domain",
					"page":        "$data.site.page",
					"gender":      "$data.user.gender",
					"yob":         "$data.user.yob",
					"currency":    "$data.cur",
				},
				"winnotice_count": bson.M{
					"$sum": "$win_notice",
				},
				"testwinnotice_count": bson.M{
					"$sum": "$test_win_notice",
				},
				"adminshare_count": bson.M{
					"$sum": "$adminshare",
				},
				"price_count": bson.M{
					"$sum": "$price",
				},
				"clickcount": bson.M{
					"$sum": "$click",
				},
				"impressioncount": bson.M{
					"$sum": "$impression",
				},
			},
		},
	}

	var (
		reqresult []ReqMigration
		resresult []ResMigration
		winresult []ResMigration
	)

	reqerr := collectionReq.Pipe(reqPipeline).All(&reqresult)

	if reqerr != nil {
		logger.Log.Println(reqerr)
	}

	reserr := collectionRes.Pipe(resPipeline).All(&resresult)
	if reserr != nil {
		logger.Log.Println(reserr)
	}

	winerr := collectionWin.Pipe(winPipeline).All(&winresult)
	if winerr != nil {
		logger.Log.Println(winerr)
	}

	var dbarray string

	if reqresult != nil {

		for index, m := range reqresult {

			var v = m.Request

			decodedValue, err := url.QueryUnescape(v.Page)
			if err != nil {
				v.Page = decodedValue
			}

			dbQ := fmt.Sprintf("('%s',%d,%d,'"+v.Country+"','"+v.Domain+"','"+v.Os+"','"+v.Ip+"','"+v.Ua+"','"+v.Language+"','"+v.Currency+"',%d,'"+v.Gender+"',%d,'"+v.Make+"','"+v.Model+"','", v.Zone_id, v.Banner_type, v.BidderID, y-int(v.Yob), v.Device_type) + v.Page + "','" + v.Ref + fmt.Sprintf("',%d,'%s','%s')", m.Request_count, datetime, time.Now().UTC().Format("2006-01-02 15:04:05"))

			dbarray = dbarray + dbQ
			if len(reqresult) != index+1 {
				dbarray = dbarray + ","
			}

		}
	}

	if dbarray != "" {

		stinsert0, err := db.DbQuery("INSERT INTO " + migration_table + " (zone_id,banner_type,bidderid,country,domain,os,ip,user_agent,language,currency,age,gender,device_type,device_make,device_model,page_url,ref_url,request_count,data_hour,date_created) VALUES " + dbarray)

		if err != nil {
			logger.Log.Println(err.Error())
			fmt.Println("Req")
			fmt.Println()
			fmt.Println(err.Error())
		}
		defer stinsert0.Close()

		// Reqquery := "INSERT INTO " + migration_table + " (zone_id,banner_type,bidderid,country,domain,os,ip,user_agent,language,currency,age,gender,device_type,device_make,device_model,page_url,ref_url,request_count,data_hour,date_created) VALUES " + dbarray + ";"
		// fmt.Println("sql query : ", Reqquery)

		// data, _ := ioutil.ReadFile("sql/rv_dj_ssp_advanced_reports_reqbkt.sql")
		// jsContent := string(data)

		// SQL_iNSERT := Reqquery

		// jsContent = strings.ReplaceAll(jsContent, "SQL_INSERT", SQL_iNSERT)

		// content := []byte(jsContent)
		// err := ioutil.WriteFile("sql/rv_dj_ssp_advanced_reports_reqbkt.sql", content, 0644)
		// if err != nil {
		// 	fmt.Println("Error writing to file:", err)

		// }

		// // Set the CSV file path
		// FilePath := constants.SQLFile + "/rv_dj_ssp_advanced_reports_reqbkt.sql"

		// // Build the mysql command
		// cmd := exec.Command(
		// 	"mysql",
		// 	"--host", constants.DbHost,
		// 	"--port", constants.DbPort,
		// 	"--user", constants.DbUser,
		// 	"--password="+constants.DbPass,
		// 	"--database", constants.DbName,
		// 	"--execute", "source "+FilePath,
		// )

		// // Set the environment variable to allow processing the SQL file
		// cmd.Env = append(os.Environ(), "MYSQL_PWD="+constants.DbPass)

		// // Execute the command
		// output, err := cmd.CombinedOutput()
		// if err != nil {
		// 	fmt.Println("Error running mysql command:", err)
		// 	fmt.Println("if o/p", string(output))
		// } else {
		// 	fmt.Println("else o/p", string(output))
		// }

		// fmt.Println("request sql file replace start")

		// dataaa, _ := ioutil.ReadFile("sql/rv_dj_ssp_advanced_reports_reqbkt.sql")
		// jsContenttt := string(dataaa)

		// SQL_iNSERTt := "SQL_INSERT"

		// jsContenttt = strings.ReplaceAll(jsContenttt, fmt.Sprint(Reqquery), SQL_iNSERTt)

		// contentttt := []byte(jsContenttt)
		// errq := ioutil.WriteFile("sql/rv_dj_ssp_advanced_reports_reqbkt.sql", contentttt, 0644)
		// if errq != nil {
		// 	fmt.Println("Error writing to file:", errq)

		// }
		// fmt.Println("request sql file replace complete")

		fmt.Println("Request completed")
	}

	var dbarrayRes string

	if resresult != nil {
		for index, v := range resresult {

			var r = v.Response

			decodedValue, err := url.QueryUnescape(r.Page)
			if err != nil {
				r.Page = decodedValue
			}

			dbQ := fmt.Sprintf("('%s',%d,%d,'"+r.Country+"','"+r.Domain+"','"+r.Os+"','"+r.Ip+"','"+r.Ua+"','"+r.Language+"','"+r.Currency+"',%d,'"+r.Gender+"',%d,'"+r.Make+"','"+r.Model+"','", r.Zone_id, r.Banner_type, r.BidderID, y-int(r.Yob), r.Device_type) + r.Page + "','" + r.Ref + fmt.Sprintf("',%d,%d,%d,%f,%f,%d,%d,'%s','%s')", v.Response_count, v.Winnotice_count, v.TestWinnotice_count, v.Adminshare_count, v.Price_count, v.Click_count, v.Impression_count, datetime, time.Now().UTC().Format("2006-01-02 15:04:05"))
			fmt.Println(dbQ)
			fmt.Println("d")

			dbarrayRes = dbarrayRes + dbQ
			if len(resresult) != index+1 {
				dbarrayRes = dbarrayRes + ","
			}

		}
	}

	if len(dbarrayRes) > 0 {

		stinsert, err := db.DbQuery("INSERT INTO " + migration_table + " (zone_id,banner_type,bidderid,country,domain,os,ip,user_agent,language,currency,age,gender,device_type,device_make,device_model,page_url,ref_url,response_count,win_notice_count,test_win_notice_count,admin_share,total_amount,click_count,impression_count,data_hour,date_created) VALUES " + dbarrayRes)

		if err != nil {
			logger.Log.Println(err.Error())
			fmt.Println("Res")

		}
		defer stinsert.Close()

		// Resquery := "INSERT INTO " + migration_table + " (zone_id,banner_type,bidderid,country,domain,os,ip,user_agent,language,currency,age,gender,device_type,device_make,device_model,page_url,ref_url,response_count,win_notice_count,test_win_notice_count,admin_share,total_amount,click_count,impression_count,data_hour,date_created) VALUES " + dbarrayRes + ";"
		// fmt.Println("sql response query : ", Resquery)

		// data, _ := ioutil.ReadFile("sql/rv_dj_ssp_advanced_reports_resbkt.sql")
		// jsContent := string(data)

		// SQL_iNSERT := Resquery

		// jsContent = strings.ReplaceAll(jsContent, "SQL_INSERT", SQL_iNSERT)

		// content := []byte(jsContent)
		// err := ioutil.WriteFile("sql/rv_dj_ssp_advanced_reports_resbkt.sql", content, 0644)
		// if err != nil {
		// 	fmt.Println("Error writing to file:", err)

		// }

		// // Set the CSV file path
		// FilePath := constants.SQLFile + "/rv_dj_ssp_advanced_reports_resbkt.sql"

		// // Build the mysql command
		// cmd := exec.Command(
		// 	"mysql",
		// 	"--host", constants.DbHost,
		// 	"--port", constants.DbPort,
		// 	"--user", constants.DbUser,
		// 	"--password="+constants.DbPass,
		// 	"--database", constants.DbName,
		// 	"--execute", "source "+FilePath,
		// )

		// // Set the environment variable to allow processing the SQL file
		// cmd.Env = append(os.Environ(), "MYSQL_PWD="+constants.DbPass)

		// // Execute the command
		// output, err := cmd.CombinedOutput()
		// if err != nil {
		// 	log.Fatal("Error running mysql command:", err)
		// 	log.Fatal(string(output))
		// }

		// fmt.Println("response sql file replace start")

		// dataaa, _ := ioutil.ReadFile("sql/rv_dj_ssp_advanced_reports_resbkt.sql")
		// jsContenttt := string(dataaa)

		// SQL_iNSERTt := "SQL_INSERT"

		// jsContenttt = strings.ReplaceAll(jsContenttt, fmt.Sprint(Resquery), SQL_iNSERTt)

		// contentttt := []byte(jsContenttt)
		// errq := ioutil.WriteFile("sql/rv_dj_ssp_advanced_reports_resbkt.sql", contentttt, 0644)
		// if errq != nil {
		// 	fmt.Println("Error writing to file:", errq)

		// }
		// fmt.Println("response sql file replace complete")

		fmt.Println("response completed")

	}

	var dbarrayWin string

	if winresult != nil {
		for index, v := range winresult {

			var r = v.Response
			decodedValue, err := url.QueryUnescape(r.Page)
			if err != nil {
				r.Page = decodedValue
			}
			dbQ := fmt.Sprintf("('%s',%d,%d,'"+r.Country+"','"+r.Domain+"','"+r.Os+"','"+r.Ip+"','"+r.Ua+"','"+r.Language+"','"+r.Currency+"',%d,'"+r.Gender+"',%d,'"+r.Make+"','"+r.Model+"','", r.Zone_id, r.Banner_type, r.BidderID, y-int(r.Yob), r.Device_type)

			dbQ = dbQ + r.Page + "','" + r.Ref

			dbQ = dbQ + fmt.Sprintf("',%d,%d,%d,%f,%f,%d,%d,'%s','%s')", v.Response_count, v.Winnotice_count, v.TestWinnotice_count, v.Adminshare_count, v.Price_count, v.Click_count, v.Impression_count, datetime, time.Now().UTC().Format("2006-01-02 15:04:05"))

			//~ dbarrayWin = append(dbarrayWin,dbQ)

			dbarrayWin = dbarrayWin + dbQ
			if len(winresult) != index+1 {
				dbarrayWin = dbarrayWin + ","
			}

		}
	}

	if len(dbarrayWin) > 0 {

		// fmt.Println("INSERT INTO " + migration_table + " (zone_id,banner_type,bidderid,country,domain,os,ip,user_agent,language,currency,age,gender,device_type,device_make,device_model,page_url,ref_url,response_count,win_notice_count,test_win_notice_count,admin_share,total_amount,click_count,impression_count,data_hour,date_created) VALUES " + dbarrayWin)

		stinsert1, err := db.DbQuery("INSERT INTO " + migration_table + " (zone_id,banner_type,bidderid,country,domain,os,ip,user_agent,language,currency,age,gender,device_type,device_make,device_model,page_url,ref_url,response_count,win_notice_count,test_win_notice_count,admin_share,total_amount,click_count,impression_count,data_hour,date_created) VALUES " + dbarrayWin)

		if err != nil {
			logger.Log.Println(err.Error())
			fmt.Println("wim")

		}
		defer stinsert1.Close()

		// Winquery := "INSERT INTO " + migration_table + " (zone_id,banner_type,bidderid,country,domain,os,ip,user_agent,language,currency,age,gender,device_type,device_make,device_model,page_url,ref_url,response_count,win_notice_count,test_win_notice_count,admin_share,total_amount,click_count,impression_count,data_hour,date_created) VALUES " + dbarrayWin + ";"
		// fmt.Println("sql response query : ", Winquery)

		// data, _ := ioutil.ReadFile("sql/rv_dj_ssp_advanced_reports_winbkt.sql")
		// jsContent := string(data)

		// SQL_iNSERT := Winquery

		// jsContent = strings.ReplaceAll(jsContent, "SQL_INSERT", SQL_iNSERT)

		// content := []byte(jsContent)
		// err := ioutil.WriteFile("sql/rv_dj_ssp_advanced_reports_winbkt.sql", content, 0644)
		// if err != nil {
		// 	fmt.Println("Error writing to file:", err)

		// }

		// // Set the CSV file path
		// FilePath := constants.SQLFile + "rv_dj_ssp_advanced_reports_winbkt.sql"

		// // Build the mysql command
		// cmd := exec.Command(
		// 	"mysql",
		// 	"--host", constants.DbHost,
		// 	"--port", constants.DbPort,
		// 	"--user", constants.DbUser,
		// 	"--password="+constants.DbPass,
		// 	"--database", constants.DbName,
		// 	"--execute", "source "+FilePath,
		// )

		// // Set the environment variable to allow processing the SQL file
		// cmd.Env = append(os.Environ(), "MYSQL_PWD="+constants.DbPass)

		// // Execute the command
		// output, err := cmd.CombinedOutput()
		// if err != nil {
		// 	log.Fatal("Error running mysql command:", err)
		// 	log.Fatal(string(output))
		// }

		// fmt.Println("response sql file replace start")

		// dataaa, _ := ioutil.ReadFile("sql/rv_dj_ssp_advanced_reports_winbkt.sql")
		// jsContenttt := string(dataaa)

		// SQL_iNSERTt := "SQL_INSERT"

		// jsContenttt = strings.ReplaceAll(jsContenttt, fmt.Sprint(Winquery), SQL_iNSERTt)

		// contentttt := []byte(jsContenttt)
		// errq := ioutil.WriteFile("sql/rv_dj_ssp_advanced_reports_winbkt.sql", contentttt, 0644)
		// if errq != nil {
		// 	fmt.Println("Error writing to file:", errq)

		// }
		// fmt.Println("win sql file replace complete")

		fmt.Println("win completed")
	}

	logger.Log.Println("MongoDB to MYSQL Migration ended at " + time.Now().Format("2006-01-02 15:04:05"))
	log.Println("MongoDB to MYSQL Migration ended at " + time.Now().Format("2006-01-02 15:04:05"))
	fmt.Println("mongo cron finished")
}

// Function for processing Mysql to Mysql Cron
func processSspMysqlCron() {
	// Mysql tables
	var report_table = constants.TablePrefix + "dj_ssp_advanced_reports"
	var migration_table = constants.TablePrefix + "dj_ssp_advanced_reports_bkt"
	var country_table = constants.TablePrefix + "country"

	defer func() {
		if err := recover(); err != nil {
			logger.Log.Println("Error occured : ", err, " Recovered from panic")
		}
	}()

	t := time.Now()
	yC := t.Year()
	monC := AddZeros(int(t.Month()))
	dC := AddZeros(t.Day())
	hC := AddZeros(t.Hour())

	layout := "2006-01-02 15:04:00"
	str := strconv.Itoa(yC) + "-" + monC + "-" + dC + " " + hC + ":00:00"
	t, _ = time.Parse(layout, str)
	logger.Log.Println("MYSQL to MYSQL Migration started at " + time.Now().Format("2006-01-02 15:04:00"))

	start := t.Add(time.Duration(-1200) * time.Minute).Format("2006-01-02 15:04:05")
	end := t.Add(time.Duration(+150) * time.Minute).Format("2006-01-02 15:04:05")

	// start := "2023-12-26 08:00:00"
	// end := "2023-12-26 08:59:00"
	sel_data := "bidderid,banner_type,zone_id,country,domain,os,ip,user_agent,language,currency,age,gender,device_type,device_make,device_model,page_url,ref_url,SUM(request_count) as request_count, SUM(response_count) as response_count,SUM(win_notice_count) as win_notice_count,SUM(test_win_notice_count) as test_win_notice_count,SUM(click_count) as click_count,SUM(impression_count) as impression_count,SUM(total_amount) as total_amount,SUM(admin_share) as admin_share"
	whr := "data_hour BETWEEN '" + start + "' AND '" + end + "'"
	group_by := "bidderid,country,domain,os,ip,user_agent,language,currency,age,gender,device_type,device_make,device_model,page_url,ref_url"
	rows, err := db.DbQuery("SELECT " + sel_data + " FROM " + migration_table + " WHERE " + whr + " GROUP BY " + group_by)

	fmt.Println("SELECT " + sel_data + " FROM " + migration_table + " WHERE " + whr + " GROUP BY " + group_by)

	defer func() {
		err := rows.Close()
		if err != nil {
			logger.Log.Println(err)
			log.Println(err)
		}
	}()

	// var Migration string = "INSERT INTO " + report_table + " (bidderid,banner_type,zone_id,country,country_name,domain,os,ip,user_agent,browser,language,currency,age,gender,device_type,device_make,device_model,page_url,ref_url,request_count,response_count,win_notice_count,test_win_notice_count,click_count,impression_count,total_amount,admin_share,datatime,date_created) VALUES "
	// var i int = 0
	if err != nil {
		logger.Log.Println(err)
	} else {
		for rows.Next() {
			var (
				bidderid              int
				banner_type           int
				zone_id               int
				geo_country           sql.NullString
				site_domain           sql.NullString
				device_os             sql.NullString
				device_ip             sql.NullString
				device_user_agent     sql.NullString
				device_language       sql.NullString
				currency              sql.NullString
				user_age              sql.NullInt64
				user_gender           sql.NullString
				device_type           sql.NullInt64
				device_make           sql.NullString
				device_model          sql.NullString
				site_page_url         sql.NullString
				site_ref_url          sql.NullString
				request_count         sql.NullInt64
				response_count        sql.NullInt64
				win_notice_count      sql.NullInt64
				test_win_notice_count sql.NullInt64
				click_count           sql.NullInt64
				impression_count      sql.NullInt64
				total_amount          sql.NullFloat64
				admin_share           sql.NullFloat64
			)
			err2 := rows.Scan(&bidderid, &banner_type, &zone_id, &geo_country, &site_domain, &device_os, &device_ip, &device_user_agent, &device_language, &currency, &user_age, &user_gender, &device_type, &device_make, &device_model, &site_page_url, &site_ref_url, &request_count, &response_count, &win_notice_count, &test_win_notice_count, &click_count, &impression_count, &total_amount, &admin_share)
			if err2 != nil {
				logger.Log.Println(err2)
				log.Println(err2)
			} else {

				var geo_country_name string
				db.DbQueryRow("SELECT name  FROM " + country_table + "  WHERE country_code = '" + geo_country.String + "' OR iso_countycode_alpha3  = '" + geo_country.String + "'  LIMIT 1").Scan(&geo_country_name)

				userAgent := device_user_agent.String
				ua := user_agent.New(userAgent)
				browser, _ := ua.Browser()
				device := ua.Mobile()

				devicetype := 2
				if device == true {
					devicetype = 1
				}

				_, err := db.DbQuery("INSERT INTO "+report_table+" (bidderid,banner_type,zone_id,country,country_name,domain,os,ip,user_agent,browser,language,currency,age,gender,device_type,device_make,device_model,page_url,ref_url,request_count,response_count,win_notice_count,test_win_notice_count,click_count,impression_count,total_amount,admin_share,datatime,date_created) VALUES(?,?,?,'"+geo_country.String+"','"+geo_country_name+"','"+site_domain.String+"','"+device_os.String+"','"+device_ip.String+"','"+device_user_agent.String+"','"+browser+"','"+device_language.String+"','"+currency.String+"',?,'"+user_gender.String+"',?,'"+device_make.String+"','"+device_model.String+"','"+site_page_url.String+"','"+site_ref_url.String+"',?,?,?,?,?,?,?,?,?,?)", bidderid, banner_type, zone_id, int(user_age.Int64), devicetype, int(request_count.Int64), int(response_count.Int64), int(win_notice_count.Int64), int(test_win_notice_count.Int64), int(click_count.Int64), int(impression_count.Int64), float64(total_amount.Float64), float64(admin_share.Float64), start, time.Now().Format("2006-01-02 15:04:05"))

				if err != nil {
					logger.Log.Println(err)
					log.Println(err)
				}
				// 		if i == 0 {
				// 			Migration = Migration + "('" + fmt.Sprint(bidderid) + "','" + fmt.Sprint(banner_type) + "','" + fmt.Sprint(zone_id) + "','" + geo_country.String + "','" + geo_country_name + "','" + site_domain.String + "','" + device_os.String + "','" + device_ip.String + "','" + device_user_agent.String + "','" + browser + "','" + device_language.String + "','" + currency.String + "','" + fmt.Sprint(int(user_age.Int64)) + "','" + user_gender.String + "','" + fmt.Sprint(devicetype) + "','" + device_make.String + "','" + device_model.String + "','" + site_page_url.String + "','" + site_ref_url.String + "','" + fmt.Sprint(int(request_count.Int64)) + "','" + fmt.Sprint(int(response_count.Int64)) + "','" + fmt.Sprint(int(win_notice_count.Int64)) + "','" + fmt.Sprint(int(test_win_notice_count.Int64)) + "','" + fmt.Sprint(int(click_count.Int64)) + "','" + fmt.Sprint(int(impression_count.Int64)) + "','" + fmt.Sprint(float64(total_amount.Float64)) + "','" + fmt.Sprint(float64(admin_share.Float64)) + "','" + start + "','" + fmt.Sprint(time.Now().Format("2006-01-02 15:04:05")) + "')"
				// 		} else {
				// 			Migration = Migration + ",('" + fmt.Sprint(bidderid) + "','" + fmt.Sprint(banner_type) + "','" + fmt.Sprint(zone_id) + "','" + geo_country.String + "','" + geo_country_name + "','" + site_domain.String + "','" + device_os.String + "','" + device_ip.String + "','" + device_user_agent.String + "','" + browser + "','" + device_language.String + "','" + currency.String + "','" + fmt.Sprint(int(user_age.Int64)) + "','" + user_gender.String + "','" + fmt.Sprint(devicetype) + "','" + device_make.String + "','" + device_model.String + "','" + site_page_url.String + "','" + site_ref_url.String + "','" + fmt.Sprint(int(request_count.Int64)) + "','" + fmt.Sprint(int(response_count.Int64)) + "','" + fmt.Sprint(int(win_notice_count.Int64)) + "','" + fmt.Sprint(int(test_win_notice_count.Int64)) + "','" + fmt.Sprint(int(click_count.Int64)) + "','" + fmt.Sprint(int(impression_count.Int64)) + "','" + fmt.Sprint(float64(total_amount.Float64)) + "','" + fmt.Sprint(float64(admin_share.Float64)) + "','" + start + "','" + fmt.Sprint(time.Now().Format("2006-01-02 15:04:05")) + "')"
				// 		}
				// 		i++
				// 	}
				// }
				// Migration += ";"
				// fmt.Println("Mysql res query : ", Migration)
				// rows.Close()

				// resdataata, _ := ioutil.ReadFile("sql/rv_dj_ssp_advanced_reports.sql")
				// resjsContent := string(resdataata)

				// RES_SQL_iNSERT := Migration

				// resjsContent = strings.ReplaceAll(resjsContent, "SQL_INSERT", RES_SQL_iNSERT)

				// rescontent := []byte(resjsContent)
				// reserr1 := ioutil.WriteFile("sql/rv_dj_ssp_advanced_reports.sql", rescontent, 0644)
				// if reserr1 != nil {
				// 	fmt.Println("Error writing to file:", reserr1)

				// }

				// // Set the CSV file path
				// ResFilePath := constants.SQLFile + "/rv_dj_ssp_advanced_reports.sql"

				// // Build the mysql command
				// rescmd := exec.Command(
				// 	"mysql",
				// 	"--host", constants.DbHost,
				// 	"--port", constants.DbPort,
				// 	"--user", constants.DbUser,
				// 	"--password="+constants.DbPass,
				// 	"--database", constants.DbName,
				// 	"--execute", "source "+ResFilePath,
				// )

				// // Set the environment variable to allow processing the SQL file
				// rescmd.Env = append(os.Environ(), "MYSQL_PWD="+constants.DbPass)

				// // Execute the command
				// _, reserr := rescmd.CombinedOutput()
				// if reserr != nil {
				// 	fmt.Println(reserr)
				// }

				// fmt.Println("response file replace start")

				// resdataaa, _ := ioutil.ReadFile("sql/rv_dj_ssp_advanced_reports.sql")
				// resjsContenttt := string(resdataaa)

				// Res_SQL_iNSERTt := "SQL_INSERT"

				// resjsContenttt = strings.ReplaceAll(resjsContenttt, fmt.Sprint(Migration), Res_SQL_iNSERTt)

				// rescontentttt := []byte(resjsContenttt)
				// reserrq := ioutil.WriteFile("sql/rv_dj_ssp_advanced_reports.sql", rescontentttt, 0644)
				// if reserrq != nil {
				// 	fmt.Println("Error writing to file:", reserrq)

				// }
				// fmt.Println("response file replace completed")
			}
		}

		fmt.Println("Mysql Response completed")
		db.DbQueryRow("delete from " + migration_table + " where " + whr)
		logger.Log.Println("MYSQL to MYSQL Migration ended at " + time.Now().Format("2006-01-02 15:04:00"))
		log.Println("MYSQL to MYSQL Migration ended at " + time.Now().Format("2006-01-02 15:04:00"))
	}
}

// Function for processing Loss Notice request
func processVastTracking(w http.ResponseWriter, r *http.Request) {
	zoneid, _ := strconv.Atoi(r.URL.Query().Get("zoneid"))
	exchangeid, _ := strconv.Atoi(r.URL.Query().Get("exchangeid"))
	event := r.URL.Query().Get("event")
	err, insert := mongoClient.MongoSaveVastCount(zoneid, exchangeid, event)
	fmt.Println("event", event)
	if insert != true {
		logger.Log.Println("Error : ", err.Error())
	}
	return
}

// Function for adding extra zeros
func AddZeros(count int) (result string) {
	if len(strconv.Itoa(count)) == 1 {
		result = "0" + strconv.Itoa(count)
	} else {
		result = strconv.Itoa(count)
	}
	return
}

// Function for processing Vast Mongo to Mysql Cron
func processVastMongoCron() {
	// Mysql Migration table
	var migration_table = constants.TablePrefix + "dsp_video_report"
	defer func() {
		if err := recover(); err != nil {
			logger.Log.Println("Error occured : ", err, " Recovered from panic")
		}
	}()

	// Migration Vast struct
	type VastMigration struct {
		Vast  mongoClient.VastCount `json:"_id" bson:"_id"`
		Count int                   `json:"count" bson:"count"`
	}

	t := time.Now()
	yC := t.Year()
	monC := AddZeros(int(t.Month()))
	dC := AddZeros(t.Day())
	hC := AddZeros(t.Hour())

	layout := "2006-01-02 15:04:00"
	str := strconv.Itoa(yC) + "-" + monC + "-" + dC + " " + hC + ":00:00"
	t, _ = time.Parse(layout, str)
	logger.Log.Println("Vast MongoDB to MYSQL Migration started at " + time.Now().Format("2006-01-02 15:04:05"))
	to := t.Add(time.Duration(-60) * time.Minute)
	y := to.Year()
	mon := int(to.Month())
	d := to.Day()
	h := to.Hour()
	min := GetMin(to.Minute())

	tableSuffix := strconv.Itoa(y) + strconv.Itoa(mon) + strconv.Itoa(d) + strconv.Itoa(h) + strconv.Itoa(min)
	fmt.Println(tableSuffix)

	datetime := strconv.Itoa(y) + "-" + strconv.Itoa(mon) + "-" + strconv.Itoa(d) + " " + strconv.Itoa(h) + ":00:00"
	// Get a handle for mongo request collection
	client, collection := mongoClient.MongoCollection(constants.MongoVastTable + "_" + tableSuffix)
	// client, collection := mongoClient.MongoCollection(constants.MongoVastTable + "_20231226120")
	defer client.Close()
	vPipeline := []bson.M{
		{
			"$group": bson.M{
				"_id": bson.M{
					"exchangeid": "$exchangeid",
					"zoneid":     "$zoneid",
					"event":      "$event",
				},
				"count": bson.M{
					"$sum": 1,
				},
			},
		},
	}
	var (
		vresult []VastMigration
	)
	err := collection.Pipe(vPipeline).All(&vresult)
	if err != nil {
		logger.Log.Println(err)
	}
	var Vast string = "INSERT INTO " + migration_table + " (zone_id,exchange_id,datetime,event,count) VALUES "
	var i int = 0
	if vresult != nil {
		for _, v := range vresult {

			if i == 0 {
				Vast = Vast + "('" + fmt.Sprint(v.Vast.Zoneid) + "','" + fmt.Sprint(v.Vast.Exchangeid) + "','" + datetime + "','" + v.Vast.Event + "','" + fmt.Sprint(v.Count) + "')"
			} else {
				Vast = Vast + ",('" + fmt.Sprint(v.Vast.Zoneid) + "','" + fmt.Sprint(v.Vast.Exchangeid) + "','" + datetime + "','" + v.Vast.Event + "','" + fmt.Sprint(v.Count) + "')"
			}
			i++
			// _, err := db.DbQuery("INSERT INTO "+migration_table+" (zone_id,exchange_id,datetime,event,count) VALUES(?,?,?,'"+v.Vast.Event+"',?)", v.Vast.Zoneid, v.Vast.Exchangeid, datetime, v.Count)
			// if err != nil {
			// 	logger.Log.Println(err.Error())
			// }
		}

		Vast += ";"
		fmt.Println("sql query : ", Vast)

		data, _ := ioutil.ReadFile("sql/rv_dsp_video_report.sql")
		jsContent := string(data)

		SQL_iNSERT := Vast

		jsContent = strings.ReplaceAll(jsContent, "SQL_INSERT", SQL_iNSERT)

		content := []byte(jsContent)
		err := ioutil.WriteFile("sql/rv_dsp_video_report.sql", content, 0644)
		if err != nil {
			fmt.Println("Error writing to file:", err)

		}

		// Set the CSV file path
		FilePath := constants.SQLFile + "/rv_dsp_video_report.sql"

		// Build the mysql command
		cmd := exec.Command(
			"mysql",
			"--host", constants.DbHost,
			"--port", constants.DbPort,
			"--user", constants.DbUser,
			"--password="+constants.DbPass,
			"--database", constants.DbName,
			"--execute", "source "+FilePath,
		)

		// Set the environment variable to allow processing the SQL file
		cmd.Env = append(os.Environ(), "MYSQL_PWD="+constants.DbPass)

		// Execute the command
		output, err := cmd.CombinedOutput()
		if err != nil {
			log.Fatal("Error running mysql command:", err)
			log.Fatal(string(output))
		}

		fmt.Println("request sql file replace start")

		dataaa, _ := ioutil.ReadFile("sql/rv_dsp_video_report.sql")
		jsContenttt := string(dataaa)

		SQL_iNSERTt := "SQL_INSERT"

		jsContenttt = strings.ReplaceAll(jsContenttt, fmt.Sprint(Vast), SQL_iNSERTt)

		contentttt := []byte(jsContenttt)
		errq := ioutil.WriteFile("sql/rv_dsp_video_report.sql", contentttt, 0644)
		if errq != nil {
			fmt.Println("Error writing to file:", errq)

		}
		fmt.Println("request sql file replace complete")

		fmt.Println("Request completed")
	}

	logger.Log.Println("Vast Mongo to MYSQL Migration ended at " + time.Now().Format("2006-01-02 15:04:00"))
}

// Cron Function
func executeCronJob() {
	// Mongo migration cron for every 15 Minutes
	gocron.Every(15).Minute().Do(processSspMongoCron)
	gocron.Every(5).Minute().Do(processRedisCron)

	// Mysql migration cron for every hour
	gocron.Every(1).Hour().Do(processSspMysqlCron)

	// Vast migration cron for every hour
	gocron.Every(1).Hour().Do(processVastMongoCron)
	<-gocron.Start()
}

func main() {
	// Concurrently execute cron functions
	go executeCronJob()
	// processSspMongoCron()
	// processSspMysqlCron()
	// processVastMongoCron()

	ipAddr := constants.AppHost
	logger.Log.Println("Server started at " + constants.AppProtocol + ipAddr + constants.AppPort)
	log.Println("Server started at " + constants.AppProtocol + ipAddr + constants.AppPort)

	// http.Handler
	router := mux.NewRouter().StrictSlash(true)
	router.HandleFunc("/", home)
	router.HandleFunc("/loaderio-492353c0ec8629e10bc4d816e68b7e76.txt", validataion).Methods("GET")
	router.HandleFunc("/loaderio-492353c0ec8629e10bc4d816e68b7e76", validataion).Methods("GET")
	router.HandleFunc("/loaderio-492353c0ec8629e10bc4d816e68b7e76.html	", validataion).Methods("GET")

	router.HandleFunc(constants.SSPEndPoint, processRequest).Methods("POST")
	router.HandleFunc(constants.WinNoticeEndPoint, processWinnotice).Methods("GET")
	router.HandleFunc(constants.BillingNoticeEndPoint, processBillingnotice).Methods("GET")
	router.HandleFunc(constants.ImpUrlEndPoint, processImpUrl).Methods("GET")
	router.HandleFunc(constants.LossNoticeEndPoint, processLossnotice).Methods("GET")
	router.HandleFunc(constants.VastWrapperEndPoint, processVastWrapper).Methods("GET")
	router.HandleFunc(constants.VastTrackingEndPoint, processVastTracking).Methods("GET")
	router.HandleFunc("/VastWrapper", VastWrapper).Methods("GET")
	srv := &http.Server{
		Addr:    constants.AppPort,
		Handler: router,
		TLSConfig: &tls.Config{
			MinVersion:               tls.VersionTLS13,
			PreferServerCipherSuites: true,
		},
	}
	if err := srv.ListenAndServeTLS(constants.CertFile, constants.KeyFile); err != nil {
		panic(err)
	}

	// if err := http.ListenAndServe(constants.AppPortraw, router); err != nil {
	// 	panic(err)
	// }
}
