package imitater

import (
	"encoding/json"
	"log"
	"time"

	"474420502.top/test/logdb"

	"474420502.top/eson/structure/circular_linked"
	uuid "github.com/satori/go.uuid"

	"474420502.top/eson/crontabex"
	"474420502.top/eson/curl2info"
	"474420502.top/eson/requests"
)

// Task 任务
type Task struct {
	ITask

	name     string
	crontab  *crontab.Crontab
	curl     *curl2info.CURL
	workflow *requests.Workflow
	session  *requests.Session
	proxies  clinked.CircularLinked
	adinfo   ADInfo
}

// Init 初始化, 会被Persion默认调用, 可以用来覆盖
func (task *Task) Init() {

}

// SetName 任务的名字
func (task *Task) SetName(name string) {
	task.name = name
}

// GetName 获取任务的名字
func (task *Task) GetName() string {
	return task.name
}

// SetCurl 设置任务的curl信息类
func (task *Task) SetCurl(curl *curl2info.CURL) {
	task.curl = curl
}

// GetCurl 获取任务的curl信息类
func (task *Task) GetCurl() *curl2info.CURL {
	return task.curl
}

// AddProxies 添加代理集合
func (task *Task) AddProxies(proxy string) {
	task.proxies.Append(proxy)
}

// GetProxies 获取代理的字符串
func (task *Task) GetProxies() *clinked.CircularLinked {
	return &task.proxies
}

// SetADInfo 设置广告的信息结构
func (task *Task) SetADInfo(adinfo ADInfo) {
	task.adinfo = adinfo
}

// GetADInfo 获取广告的信息结构
func (task *Task) GetADInfo() *ADInfo {
	return &task.adinfo
}

// SetCrontab 设置crontab的控制规则字符串
func (task *Task) SetCrontab(cron string) {
	task.crontab = crontab.NewCrontab(cron)
}

// GetCrontab 设置上次执行的状态 成功true 失败false
func (task *Task) GetCrontab() *crontab.Crontab {
	return task.crontab
}

// TimeUp 判断是否到了下次执行的时间点
func (task *Task) TimeUp() bool {
	return task.crontab.TimeUp()
}

// NextTime  下次执行的时间点
func (task *Task) NextTime() time.Time {
	return task.crontab.NextTime()
}

// Workflow 根据persistent 是否返回现有session(or 新建 session),创建Workflow的信息, 便于设置或者更改参数, Session持久化
func (task *Task) Workflow(persistent bool) *requests.Workflow {

	if persistent {
		task.workflow = task.curl.CreateWorkflow(task.Session())
		return task.workflow
	}

	proxies := task.GetProxies()
	ses := task.curl.CreateSession()
	if proxies.Size() > 0 {
		proxy := proxies.Cursor().GetValue().(string)
		ses.SetConfig(requests.CProxy, proxy)
		proxies.MoveNext()
	}

	return task.curl.CreateWorkflow(ses)
}

// Request 根据curl信息执行,没持久化
func (task *Task) Request() (*requests.Response, error) {
	return task.Workflow(false).Execute()
}

// Session 获取Session的信息 只保留session的数据和url参数.
func (task *Task) Session() *requests.Session {
	if task.session == nil {
		task.session = task.curl.CreateSession()
	}
	if task.proxies.Size() > 0 {
		proxy := task.proxies.Cursor().GetValue().(string)
		task.session.SetConfig(requests.CProxy, proxy)
		task.proxies.MoveNext()
	}

	return task.session
}

// ADDataSave 公众存储数据的接口
func ADDataSave(task ITask, db *logdb.LogDB, adDataList []string) bool {
	if len(adDataList) != 0 {
		adDataStore, err := json.Marshal(adDataList)
		if err != nil {
			panic(err)
		}
		// log.Println(string(adDataStore))
		uid, err := uuid.NewV4()
		if err != nil {
			panic(err)
		}

		log.Println(uid.String())

		adinfo := task.GetADInfo()
		db.ADInsert(uid.String(), adinfo.Device, adinfo.Platform, adinfo.AreaCC, "",
			string(adDataStore), adinfo.SpiderID, adinfo.Channel, adinfo.Media, adinfo.CatchAccountID, 0, adinfo.Priority, time.Now())

		return true
	}

	return false
}
