package models

import (
	"fmt"
	"time"
)

type DnsZone struct {
	Id       int    `json:"id"`
	ZoneId   int    `json:"zone_id"`
	VendorId int    `json:"vendor_id"`
	Name     string `json:"name"`
	Status   string `json:"status"` /*enable,disable*/
	Owner    string `json:"owner"`
	Remark   string `json:"remark"`
}

type DnsRecord struct {
	Id         int       `json:"id"`
	RecordId   int64     `json:"record_id"`
	ZoneId     int       `json:"zone_id"`
	ZoneName   string    `json:"zone_name"`
	VendorId   int       `json:"vendor_id"`
	Name       string    `json:"name"`
	Type       string    `json:"type"`
	Line       string    `json:"line"`
	Ttl        int       `json:"ttl"`
	Target     string    `json:"target"`
	Status     string    `json:"status"` /*enable,disable*/
	Owner      string    `json:"owner"`
	Remark     string    `json:"remark"`
	CreateTime time.Time `json:"create_time"`
	UpdateTime time.Time `json:"update_time"`
}

func ExitDnsZoneByName(zoneName string) bool {
	var domain Domain
	db.Select("id").Where("name = ?", zoneName).First(&domain)
	if domain.Id > 0 {
		return true
	}
	return false
}

func GetDnsVendorByName(zoneName string) (vendorId int) {
	var zone DnsZone
	db.Select("vendor_id").Where("name = ?", zoneName).First(&zone)
	if zone.VendorId > 0 {
		return zone.VendorId
	}
	return 0
}

func GetDnsZones(vendorId int) (zoneNames []string) {
	selectSql := fmt.Sprintf(`SELECT DISTINCT zone_name FROM dns_record `)
	if vendorId > 0 {
		selectSql += fmt.Sprintf(`WHERE vendor_id = %d `, vendorId)
	}
	db.Raw(selectSql).Pluck("zone_name", &zoneNames)
	return
}

func GetDnsTypes() (types []string) {
	db.Raw("SELECT DISTINCT type FROM dns_record;").Pluck("type", &types)
	return
}

func CreateDnsZone(zone DnsZone) (err error) {
	isExist := ExitDnsZoneByName(zone.Name)
	if isExist {
		err = db.Model(&zone).Where("name = ?", zone.Name).Update(zone).Error
		return err
	}
	err = db.Create(&zone).Error
	return err
}

func ExitDnsRecordByRecordId(recordId int64) bool {
	var record DnsRecord
	db.Select("id").Where("record_id = ?", recordId).First(&record)
	if record.Id > 0 {
		return true
	}
	return false
}

func ExitGodaddyDnsRecord(zoneName string, name string, dType string, target string) (status bool, id int) {
	var record DnsRecord
	db.Select("id").Where("zone_name = ? AND name = ? AND type = ? AND target = ?", zoneName, name, dType, target).First(&record)
	if record.Id > 0 {
		return true, record.Id
	}
	return false, 0
}

func InitDnsRecord(record DnsRecord) (err error) {
	if record.VendorId == 9 {
		status, id := ExitGodaddyDnsRecord(record.ZoneName, record.Name, record.Type, record.Target)
		if status {
			err = db.Model(&DnsRecord{}).Where("id = ?", id).Update(record).Error
			return err
		}
	}

	if record.VendorId == 5 || record.VendorId == 10 {
		isExist := ExitDnsRecordByRecordId(record.RecordId)
		if isExist {
			err = db.Model(&record).Where("record_id = ?", record.RecordId).Update(record).Error
			return err
		}
	}

	err = db.Create(&record).Error
	return
}

func GetDnsRecord(zoneName string, recordType string, key interface{}, isMine string, pageNum int, pageSize int, currentUser string) (record []DnsRecord) {
	selectSql := fmt.Sprintf(
		`SELECT * FROM dns_record WHERE zone_name = '%s' `, zoneName)

	if recordType != "" {
		selectSql += fmt.Sprintf(`AND type = '%s' `, recordType)
	}
	if key != "" {
		selectSql += fmt.Sprintf(`AND (name LIKE '%%%s%%' OR target LIKE '%%%s%%' OR owner LIKE '%%%s%%' ) `, key, key, key)
	}
	if isMine == "true" {
		selectSql += fmt.Sprintf(`AND owner = '%s' `, currentUser)
	}
	db.Raw(selectSql).Offset(pageNum).Limit(pageSize).Scan(&record)
	return
}

func GetDnsRecordTotal(zoneName string, recordType string, key interface{}, isMine string, currentUser string) (count int) {
	selectSql := fmt.Sprintf(`SELECT COUNT(*) FROM dns_record WHERE zone_name = '%s' `, zoneName)

	if recordType != "" {
		selectSql += fmt.Sprintf(`AND type = '%s' `, recordType)
	}
	if key != "" {
		selectSql += fmt.Sprintf(`AND (name LIKE '%%%s%%' OR target LIKE '%%%s%%' OR owner LIKE '%%%s%%' ) `, key, key, key)
	}
	if isMine == "true" {
		selectSql += fmt.Sprintf(`AND owner = '%s' `, currentUser)
	}
	db.Raw(selectSql).Count(&count)
	return
}

func CreateDnsRecord(record interface{}) (err error) {
	err = db.Create(record).Error
	return
}

func UpdateDnsRecords(id int, name string, rType string, target string, ttl int, line string,
	owner string, remark string, recordIds []int) (err error) {
	//单条更新
	if len(recordIds) == 0 {
		err = db.Model(&DnsRecord{}).Where("id = ?", id).Updates(
			DnsRecord{Id: id, Name: name, Type: rType, Target: target, Ttl: ttl, Line: line, Owner: owner, Remark: remark}).Error
		return
	}

	//批量更新 owner
	err = db.Model(&DnsRecord{}).Where("id in (?)", recordIds).Updates(DnsRecord{Owner: owner}).Error
	return
}

func DeleteDnsRecord(id int) (err error) {
	err = db.Where("id = ?", id).Delete(&DnsRecord{}).Error
	return
}

func UpdateDnsRecordStatus(id int, status string) (err error) {
	err = db.Model(&DnsRecord{}).Where("id = ?", id).Update("status", status).Error
	return
}
