package repo

import (
	"fmt"
	"net/http"
	"net/url"
	"strconv"
	"strings"
	"time"

	"code.gitea.io/gitea/models"
	"code.gitea.io/gitea/modules/context"
	"code.gitea.io/gitea/modules/log"
	"code.gitea.io/gitea/modules/timeutil"
	"code.gitea.io/gitea/routers/repo"
	cloudbrainService "code.gitea.io/gitea/services/cloudbrain"
	"code.gitea.io/gitea/services/cloudbrain/resource"
	"github.com/360EntSecGroup-Skylar/excelize/v2"
)

type DateCloudbrainNum struct {
	Date                      string         `json:"date"`
	CloudOneJobTypeRes        map[string]int `json:"cloudOneJobTypeRes"`
	CloudTwoJobTypeRes        map[string]int `json:"cloudTwoJobTypeRes"`
	IntelligentNetJobTypeRes  map[string]int `json:"intelligentNetJobTypeRes"`
	CDCenterJobTypeRes        map[string]int `json:"cDCenterJobTypeRes"`
	CloudBrainPeriodNum       map[int]int    `json:"cloudBrainPeriodNum"`
	CloudBrainComputeResource map[string]int `json:"cloudBrainComputeResource"`
}
type DateCloudbrainInfo struct {
	Date                      string         `json:"date"`
	CloudBrainPeriodNum       map[int]int    `json:"cloudBrainPeriodNum"`
	CloudBrainComputeResource map[string]int `json:"cloudBrainComputeResource"`
}
type CloudbrainsStatusAnalysis struct {
	JobWaitingCount   int64 `json:"jobWaitingCount"`
	JobRunningCount   int64 `json:"jobRunningCount"`
	JobStoppedCount   int64 `json:"jobStoppedCount"`
	JobCompletedCount int64 `json:"jobCompletedCount"`
	JobFailedCount    int64 `json:"jobFailedCount"`
	JobKilledCount    int64 `json:"jobKilledCount"`
	JobInitCount      int64 `json:"jobInitCount"`
}

func GetAllCloudbrainsOverview(ctx *context.Context) {
	recordCloudbrain, err := models.GetRecordBeginTime()
	if err != nil {
		log.Error("Can not get recordCloudbrain", err)
		ctx.Error(http.StatusBadRequest, ctx.Tr("repo.record_begintime_get_err"))
		return
	}
	recordBeginTime := recordCloudbrain[0].Cloudbrain.CreatedUnix
	now := time.Now()
	beginTime := time.Date(now.Year(), now.Month(), now.Day(), 0, 0, 0, 0, now.Location())
	endTime := now
	todayCreatorCount, err := models.GetTodayCreatorCount(beginTime, endTime)
	if err != nil {
		log.Error("Can not query todayCreatorCount.", err)
		return
	}
	cloudbrainTypeCount, err := models.GetCloudbrainTypeCount()
	if err != nil {
		log.Error("Can not query cloudbrainTypeCount.", err)
		return
	}

	todayCloudbrainCount, err := models.GetTodayCloudbrainCount(beginTime, endTime)
	if err != nil {
		log.Error("Can not query todayCloudbrainCount.", err)
		return
	}

	todayRunningCount, err := models.GetTodayRunningCount(beginTime, endTime)
	if err != nil {
		log.Error("Can not query todayRunningCount.", err)
		return
	}

	todayWaitingCount, err := models.GetTodayWaitingCount(beginTime, endTime)
	if err != nil {
		log.Error("Can not query todayWaitingCount.", err)
		return
	}

	todayCompletedCount := todayCloudbrainCount - todayRunningCount - todayWaitingCount

	creatorCount, err := models.GetCreatorCount()
	if err != nil {
		log.Error("Can not query creatorCount.", err)
		return
	}

	ctx.JSON(http.StatusOK, map[string]interface{}{
		"recordBeginTime":     recordBeginTime,
		"updateTime":          now.Unix(),
		"todayCreatorCount":   todayCreatorCount,
		"creatorCount":        creatorCount,
		"todayRunningCount":   todayRunningCount,
		"todayCompletedCount": todayCompletedCount,
		"todayWaitingCount":   todayWaitingCount,
		"todayNewJobCount":    todayCloudbrainCount,
		"cloudbrainTypeCount": cloudbrainTypeCount,
	})
}
func GetOverviewDuration(ctx *context.Context) {
	durationSum := 0
	cardDurationSum := 0

	cloudBrainOneCardDuSum := 0
	cloudBrainTwoCardDuSum := 0
	c2NetCardDuSum := 0
	cDNetCardDuSum := 0

	cloudBrainOneDuration := 0
	cloudBrainTwoDuration := 0
	c2NetDuration := 0
	cDCenterDuration := 0

	cloudbrainTypeDuration, err := models.GetCloudbrainTypeCardDuration()
	if err != nil {
		log.Error("GetCloudbrainTypeCardDuration err!", err)
		return
	}
	for _, result := range cloudbrainTypeDuration {
		if result.Type == models.TypeCloudBrainOne {
			cloudBrainOneDuration = result.DurationSum
			cloudBrainOneCardDuSum = result.CardDurationSum
		}
		if result.Type == models.TypeCloudBrainTwo {
			cloudBrainTwoDuration = result.DurationSum
			cloudBrainTwoCardDuSum = result.CardDurationSum
		}
		if result.Type == models.TypeC2Net {
			c2NetDuration = result.DurationSum
			c2NetCardDuSum = result.CardDurationSum
		}
		if result.Type == models.TypeCDCenter {
			cDCenterDuration = result.DurationSum
			cDNetCardDuSum = result.CardDurationSum
		}
	}
	cloudbrainAllDuration, err := models.GetCloudbrainAllCardDuration()
	if err != nil {
		log.Error("GetCloudbrainAllCardDuration err!", err)
		return
	}
	durationSum = cloudbrainAllDuration.DurationSum
	cardDurationSum = cloudbrainAllDuration.CardDurationSum

	ctx.JSON(http.StatusOK, map[string]interface{}{
		"cloudBrainOneCardDuSum": cloudBrainOneCardDuSum,
		"cloudBrainTwoCardDuSum": cloudBrainTwoCardDuSum,
		"c2NetCardDuSum":         c2NetCardDuSum,
		"cDNetCardDuSum":         cDNetCardDuSum,
		"cardDuSum":              cardDurationSum,

		"cloudBrainOneDuration": cloudBrainOneDuration,
		"cloudBrainTwoDuration": cloudBrainTwoDuration,
		"c2NetDuration":         c2NetDuration,
		"cDCenterDuration":      cDCenterDuration,
		"durationSum":           durationSum,
	})
}

func GetCloudbrainCardDuration(task models.Cloudbrain) string {
	cardNum := int(0)
	spec, err := resource.GetCloudbrainSpec(task.ID)
	if err != nil {
		log.Info("error:" + err.Error())
		return ""
	}
	if spec != nil {
		cardNum = spec.AccCardsNum
	} else {
		cardNum = 1
	}
	var workServerNumber int64
	if task.WorkServerNumber >= 1 {
		workServerNumber = int64(task.WorkServerNumber)
	} else {
		workServerNumber = 1
	}
	cardDuration := models.ConvertDurationToStr(workServerNumber * int64(cardNum) * task.Duration)
	return cardDuration
}

func GetAllCloudbrainsTrend(ctx *context.Context) {

	queryType := ctx.QueryTrim("type")
	now := time.Now()

	beginTimeStr := ctx.QueryTrim("beginTime")
	endTimeStr := ctx.QueryTrim("endTime")
	var beginTime time.Time
	var endTime time.Time
	dateCloudbrainNum := make([]DateCloudbrainNum, 0)
	var err error
	if queryType != "" {
		if queryType == "all" {
			recordCloudbrain, err := models.GetRecordBeginTime()
			if err != nil {
				log.Error("Can not get recordCloudbrain", err)
				ctx.Error(http.StatusBadRequest, ctx.Tr("repo.record_begintime_get_err"))
				return
			}
			brainRecordBeginTime := recordCloudbrain[0].Cloudbrain.CreatedUnix.AsTime()
			beginTime = brainRecordBeginTime
			endTime = now
			dateCloudbrainNum, err = getMonthCloudbrainNum(beginTime, endTime)
			if err != nil {
				log.Error("Can not query getMonthCloudbrainNum.", err)
				ctx.Error(http.StatusBadRequest, ctx.Tr("getMonthCloudbrainNum_get_error"))
				return
			}
		} else if queryType == "today" {
			beginTime = time.Date(now.Year(), now.Month(), now.Day(), 0, 0, 0, 0, now.Location())
			// endTimeTemp = now
			endTime = beginTime.AddDate(0, 0, 1)
			dateCloudbrainNum, err = getDayCloudbrainNum(beginTime, endTime)
			if err != nil {
				log.Error("Can not query getDayCloudbrainNum.", err)
				ctx.Error(http.StatusBadRequest, ctx.Tr("getDayCloudbrainNum_get_error"))
				return
			}
		} else if queryType == "yesterday" {
			beginTime = now.AddDate(0, 0, -1)
			beginTime = time.Date(beginTime.Year(), beginTime.Month(), beginTime.Day(), 0, 0, 0, 0, now.Location())
			endTime = time.Date(now.Year(), now.Month(), now.Day(), 0, 0, 0, 0, now.Location())
			dateCloudbrainNum, err = getDayCloudbrainNum(beginTime, endTime)
			if err != nil {
				log.Error("Can not query getDayCloudbrainNum.", err)
				ctx.Error(http.StatusBadRequest, ctx.Tr("getDayCloudbrainNum_get_error"))
				return
			}
		} else if queryType == "last_7day" {
			beginTime = now.AddDate(0, 0, -6)
			beginTime = time.Date(beginTime.Year(), beginTime.Month(), beginTime.Day(), 0, 0, 0, 0, now.Location())
			endTime = now
			dateCloudbrainNum, err = getDayCloudbrainNum(beginTime, endTime)
			if err != nil {
				log.Error("Can not query getDayCloudbrainNum.", err)
				ctx.Error(http.StatusBadRequest, ctx.Tr("getDayCloudbrainNum_get_error"))
				return
			}
		} else if queryType == "last_30day" {
			beginTime = now.AddDate(0, 0, -29)
			beginTime = time.Date(beginTime.Year(), beginTime.Month(), beginTime.Day(), 0, 0, 0, 0, now.Location())
			endTime = now
			dateCloudbrainNum, err = getDayCloudbrainNum(beginTime, endTime)
			if err != nil {
				log.Error("Can not query getDayCloudbrainNum.", err)
				ctx.Error(http.StatusBadRequest, ctx.Tr("getDayCloudbrainNum_get_error"))
				return
			}
		} else if queryType == "current_month" {
			endTime = now
			beginTime = time.Date(endTime.Year(), endTime.Month(), 1, 0, 0, 0, 0, now.Location())
			dateCloudbrainNum, err = getDayCloudbrainNum(beginTime, endTime)
			if err != nil {
				log.Error("Can not query getDayCloudbrainNum.", err)
				ctx.Error(http.StatusBadRequest, ctx.Tr("getDayCloudbrainNum_get_error"))
				return
			}
		} else if queryType == "current_year" {
			endTime = now
			beginTime = time.Date(endTime.Year(), 1, 1, 0, 0, 0, 0, now.Location())
			// endTimeTemp = beginTime.AddDate(0, 1, 0)
			dateCloudbrainNum, err = getMonthCloudbrainNum(beginTime, endTime)
			if err != nil {
				log.Error("Can not query getMonthCloudbrainNum.", err)
				ctx.Error(http.StatusBadRequest, ctx.Tr("getMonthCloudbrainNum_get_error"))
				return
			}
		} else if queryType == "last_month" {

			lastMonthTime := now.AddDate(0, -1, 0)
			beginTime = time.Date(lastMonthTime.Year(), lastMonthTime.Month(), 1, 0, 0, 0, 0, now.Location())
			endTime = time.Date(now.Year(), now.Month(), 1, 0, 0, 0, 0, now.Location())
			dateCloudbrainNum, err = getDayCloudbrainNum(beginTime, endTime)
			if err != nil {
				log.Error("Can not query getDayCloudbrainNum.", err)
				ctx.Error(http.StatusBadRequest, ctx.Tr("getDayCloudbrainNum_get_error"))
				return
			}
		}

	} else {
		if beginTimeStr == "" || endTimeStr == "" {
			//如果查询类型和开始时间结束时间都未设置，按queryType=all处理
			recordCloudbrain, err := models.GetRecordBeginTime()
			if err != nil {
				log.Error("Can not get recordCloudbrain", err)
				ctx.Error(http.StatusBadRequest, ctx.Tr("repo.record_begintime_get_err"))
				return
			}
			brainRecordBeginTime := recordCloudbrain[0].Cloudbrain.CreatedUnix.AsTime()
			beginTime = brainRecordBeginTime
			endTime = now
			dateCloudbrainNum, err = getMonthCloudbrainNum(beginTime, endTime)
			if err != nil {
				log.Error("Can not query getMonthCloudbrainNum.", err)
				ctx.Error(http.StatusBadRequest, ctx.Tr("getMonthCloudbrainNum_get_error"))
				return
			}
		} else {
			beginTime, err = time.ParseInLocation("2006-01-02", beginTimeStr, time.Local)
			if err != nil {
				log.Error("Can not ParseInLocation.", err)
				ctx.Error(http.StatusBadRequest, ctx.Tr("ParseInLocation_get_error"))
				return
			}
			endTime, err = time.ParseInLocation("2006-01-02", endTimeStr, time.Local)
			if err != nil {
				log.Error("Can not ParseInLocation.", err)
				ctx.Error(http.StatusBadRequest, ctx.Tr("ParseInLocation_get_error"))
				return
			}
			if endTime.After(time.Now()) {
				endTime = time.Now()
			}
			dateCloudbrainNum, err = getDayCloudbrainNum(beginTime, endTime)
			if err != nil {
				log.Error("Can not query getDayCloudbrainNum.", err)
				ctx.Error(http.StatusBadRequest, ctx.Tr("getDayCloudbrainNum_get_error"))
				return
			}
		}

	}
	ctx.JSON(http.StatusOK, map[string]interface{}{
		"timeCloudbrainNum": dateCloudbrainNum,
	})

}
func GetAllCloudbrainsTrendDetail(ctx *context.Context) {
	queryType := ctx.QueryTrim("type")
	now := time.Now()

	beginTimeStr := ctx.QueryTrim("beginTime")
	endTimeStr := ctx.QueryTrim("endTime")
	var beginTime time.Time
	var endTime time.Time
	var endTimeTemp time.Time
	dayCloudbrainInfo := make([]DateCloudbrainInfo, 0)
	var err error
	var count int
	if queryType != "" {
		if queryType == "all" {
			recordCloudbrain, err := models.GetRecordBeginTime()
			if err != nil {
				log.Error("Can not get recordCloudbrain", err)
				ctx.Error(http.StatusBadRequest, ctx.Tr("repo.record_begintime_get_err"))
				return
			}
			brainRecordBeginTime := recordCloudbrain[0].Cloudbrain.CreatedUnix.AsTime()
			beginTime = brainRecordBeginTime
			endTime = now
			dayCloudbrainInfo, count, err = getMonthCloudbrainInfo(beginTime, endTime)
			if err != nil {
				log.Error("Can not query getDayCloudbrainInfo.", err)
				ctx.Error(http.StatusBadRequest, ctx.Tr("getDayCloudbrainInfo_get_error"))
				return
			}
		} else if queryType == "today" {
			beginTime = now.AddDate(0, 0, 0)
			beginTime = time.Date(beginTime.Year(), beginTime.Month(), beginTime.Day(), 0, 0, 0, 0, now.Location())
			endTime = now
			dayCloudbrainInfo, count, err = getDayCloudbrainInfo(beginTime, endTime)
			if err != nil {
				log.Error("Can not query getDayCloudbrainInfo.", err)
				ctx.Error(http.StatusBadRequest, ctx.Tr("getDayCloudbrainInfo_get_error"))
				return
			}

		} else if queryType == "yesterday" {
			beginTime = now.AddDate(0, 0, -1)
			beginTime = time.Date(beginTime.Year(), beginTime.Month(), beginTime.Day(), 0, 0, 0, 0, now.Location())
			endTime = time.Date(now.Year(), now.Month(), now.Day(), 0, 0, 0, 0, now.Location())
			dayCloudbrainInfo, count, err = getDayCloudbrainInfo(beginTime, endTime)
			if err != nil {
				log.Error("Can not query getDayCloudbrainInfo.", err)
				ctx.Error(http.StatusBadRequest, ctx.Tr("getDayCloudbrainInfo_get_error"))
				return
			}

		} else if queryType == "last_7day" {
			beginTime = now.AddDate(0, 0, -6)
			beginTime = time.Date(beginTime.Year(), beginTime.Month(), beginTime.Day(), 0, 0, 0, 0, now.Location())
			endTime = now
			endTimeTemp = time.Date(endTimeTemp.Year(), endTimeTemp.Month(), endTimeTemp.Day(), 0, 0, 0, 0, now.Location())
			dayCloudbrainInfo, count, err = getDayCloudbrainInfo(beginTime, endTime)
			if err != nil {
				log.Error("Can not query getDayCloudbrainInfo.", err)
				ctx.Error(http.StatusBadRequest, ctx.Tr("getDayCloudbrainInfo_get_error"))
				return
			}
		} else if queryType == "last_30day" {
			beginTime = now.AddDate(0, 0, -29)
			beginTime = time.Date(beginTime.Year(), beginTime.Month(), beginTime.Day(), 0, 0, 0, 0, now.Location())
			endTime = now
			dayCloudbrainInfo, count, err = getDayCloudbrainInfo(beginTime, endTime)
			if err != nil {
				log.Error("Can not query getDayCloudbrainInfo.", err)
				ctx.Error(http.StatusBadRequest, ctx.Tr("getDayCloudbrainInfo_get_error"))
				return
			}
		} else if queryType == "current_month" {
			endTime = now
			beginTime = time.Date(endTime.Year(), endTime.Month(), 1, 0, 0, 0, 0, now.Location())
			dayCloudbrainInfo, count, err = getDayCloudbrainInfo(beginTime, endTime)
			if err != nil {
				log.Error("Can not query getDayCloudbrainInfo.", err)
				ctx.Error(http.StatusBadRequest, ctx.Tr("getDayCloudbrainInfo_get_error"))
				return
			}

		} else if queryType == "current_year" {
			endTime = now
			beginTime = time.Date(endTime.Year(), 1, 1, 0, 0, 0, 0, now.Location())
			dayCloudbrainInfo, count, err = getMonthCloudbrainInfo(beginTime, endTime)
			if err != nil {
				log.Error("Can not query getDayCloudbrainInfo.", err)
				ctx.Error(http.StatusBadRequest, ctx.Tr("getDayCloudbrainInfo_get_error"))
				return
			}

		} else if queryType == "last_month" {

			lastMonthTime := now.AddDate(0, -1, 0)
			beginTime = time.Date(lastMonthTime.Year(), lastMonthTime.Month(), 1, 0, 0, 0, 0, now.Location())
			endTime = time.Date(now.Year(), now.Month(), 1, 0, 0, 0, 0, now.Location())
			dayCloudbrainInfo, count, err = getDayCloudbrainInfo(beginTime, endTime)
			if err != nil {
				log.Error("Can not query getDayCloudbrainInfo.", err)
				ctx.Error(http.StatusBadRequest, ctx.Tr("getDayCloudbrainInfo_get_error"))
				return
			}

		}

	} else {
		if beginTimeStr == "" || endTimeStr == "" {
			//如果查询类型和开始时间结束时间都未设置，按queryType=all处理
			recordCloudbrain, err := models.GetRecordBeginTime()
			if err != nil {
				log.Error("Can not get recordCloudbrain", err)
				ctx.Error(http.StatusBadRequest, ctx.Tr("repo.record_begintime_get_err"))
				return
			}
			brainRecordBeginTime := recordCloudbrain[0].Cloudbrain.CreatedUnix.AsTime()
			beginTime = brainRecordBeginTime
			endTime = now
			dayCloudbrainInfo, count, err = getMonthCloudbrainInfo(beginTime, endTime)
			if err != nil {
				log.Error("Can not query getDayCloudbrainInfo.", err)
				ctx.Error(http.StatusBadRequest, ctx.Tr("getDayCloudbrainInfo_get_error"))
				return
			}
		} else {
			beginTime, err = time.ParseInLocation("2006-01-02", beginTimeStr, time.Local)
			if err != nil {
				log.Error("Can not ParseInLocation.", err)
				ctx.Error(http.StatusBadRequest, ctx.Tr("ParseInLocation_get_error"))
				return
			}
			endTime, err = time.ParseInLocation("2006-01-02", endTimeStr, time.Local)
			if err != nil {
				log.Error("Can not ParseInLocation.", err)
				ctx.Error(http.StatusBadRequest, ctx.Tr("ParseInLocation_get_error"))
				return
			}
			if endTime.After(time.Now()) {
				endTime = time.Now()
			}
			endTimeTemp = beginTime.AddDate(0, 0, 1)
			dayCloudbrainInfo, count, err = getDayCloudbrainInfo(beginTime, endTime)
			if err != nil {
				log.Error("Can not query getDayCloudbrainInfo.", err)
				ctx.Error(http.StatusBadRequest, ctx.Tr("getDayCloudbrainInfo_get_error"))
				return
			}
		}

	}

	page := ctx.QueryInt("page")
	if page <= 0 {
		page = 1
	}
	pagesize := ctx.QueryInt("pagesize")
	if pagesize <= 0 {
		pagesize = 5
	}
	pageDateCloudbrainInfo := getPageDateCloudbrainInfo(dayCloudbrainInfo, page, pagesize)

	ctx.JSON(http.StatusOK, map[string]interface{}{
		"totalCount":         count,
		"timeCloudbrainInfo": pageDateCloudbrainInfo,
	})

}
func getPageDateCloudbrainInfo(dateCloudbrainInfo []DateCloudbrainInfo, page int, pagesize int) []DateCloudbrainInfo {
	begin := (page - 1) * pagesize
	end := (page) * pagesize

	if begin > len(dateCloudbrainInfo)-1 {
		return nil
	}
	if end > len(dateCloudbrainInfo)-1 {
		return dateCloudbrainInfo[begin:]
	} else {
		return dateCloudbrainInfo[begin:end]
	}

}

func getPageDateCloudbrainDuration(dateUsageStatistic []models.DateUsageStatistic, page int, pagesize int) []models.DateUsageStatistic {
	begin := (page - 1) * pagesize
	end := (page) * pagesize

	if begin > len(dateUsageStatistic)-1 {
		return nil
	}
	if end > len(dateUsageStatistic)-1 {
		return dateUsageStatistic[begin:]
	} else {
		return dateUsageStatistic[begin:end]
	}

}

func GetAllCloudbrainsPeriodDistribution(ctx *context.Context) {
	queryType := ctx.QueryTrim("type")
	beginTimeStr := ctx.QueryTrim("beginTime")
	endTimeStr := ctx.QueryTrim("endTime")
	recordCloudbrain, err := models.GetRecordBeginTime()
	if err != nil {
		log.Error("Can not get record begin time", err)
		ctx.Error(http.StatusBadRequest, ctx.Tr("repo.record_begintime_get_err"))
		return
	}
	recordBeginTime := time.Unix(int64(recordCloudbrain[0].Cloudbrain.CreatedUnix), 0)
	beginTime, endTime, err := getCloudbrainTimePeroid(ctx, recordBeginTime)
	if err != nil {
		log.Error("getCloudbrainTimePeroid error:", err)
		ctx.Error(http.StatusBadRequest, ctx.Tr("repo.parameter_is_wrong"))
		return
	}
	cloudOneJobTypeRes := make(map[string]int)
	cloudTwoJobTypeRes := make(map[string]int)
	intelligentNetJobTypeRes := make(map[string]int)
	cDCenterJobTypeRes := make(map[string]int)
	cloudBrainPeriodNum := make(map[int]int)
	cloudBrainComputeResource := make(map[string]int)
	beginTimeTemp := beginTime.Unix()
	if queryType == "all" || (queryType == "" && (beginTimeStr == "" || endTimeStr == "")) {
		beginTimeTemp = int64(recordCloudbrain[0].Cloudbrain.CreatedUnix)
	}

	page := 1
	pagesize := 10000
	count := pagesize
	//Each time a maximum of 10000 pieces of data are detected to the memory, batch processing
	for count == pagesize && count != 0 {
		cloudbrains, _, err := models.CloudbrainAllStatic(&models.CloudbrainsOptions{
			ListOptions: models.ListOptions{
				Page:     page,
				PageSize: pagesize,
			},
			Type:          models.TypeCloudBrainAll,
			BeginTimeUnix: beginTimeTemp,
			EndTimeUnix:   endTime.Unix(),
		})
		if err != nil {
			ctx.ServerError("Get cloudbrains failed:", err)
			return
		}

		for _, cloudbrain := range cloudbrains {
			if cloudbrain.Cloudbrain.Type == models.TypeCloudBrainOne {
				if _, ok := cloudOneJobTypeRes[cloudbrain.JobType]; !ok {
					cloudOneJobTypeRes[cloudbrain.JobType] = 1
				} else {
					cloudOneJobTypeRes[cloudbrain.JobType] += 1
				}
			}
			if cloudbrain.Cloudbrain.Type == models.TypeCloudBrainTwo {
				if _, ok := cloudTwoJobTypeRes[cloudbrain.JobType]; !ok {
					cloudTwoJobTypeRes[cloudbrain.JobType] = 1
				} else {
					cloudTwoJobTypeRes[cloudbrain.JobType] += 1
				}
			}
			if cloudbrain.Cloudbrain.Type == models.TypeC2Net {
				if _, ok := intelligentNetJobTypeRes[cloudbrain.JobType]; !ok {
					intelligentNetJobTypeRes[cloudbrain.JobType] = 1
				} else {
					intelligentNetJobTypeRes[cloudbrain.JobType] += 1
				}
			}
			if cloudbrain.Cloudbrain.Type == models.TypeCDCenter {
				if _, ok := cDCenterJobTypeRes[cloudbrain.JobType]; !ok {
					cDCenterJobTypeRes[cloudbrain.JobType] = 1
				} else {
					cDCenterJobTypeRes[cloudbrain.JobType] += 1
				}
			}

			if _, ok := cloudBrainPeriodNum[cloudbrain.Cloudbrain.Type]; !ok {
				cloudBrainPeriodNum[cloudbrain.Cloudbrain.Type] = 1
			} else {
				cloudBrainPeriodNum[cloudbrain.Cloudbrain.Type] += 1
			}

			if _, ok := cloudBrainComputeResource[cloudbrain.Cloudbrain.ComputeResource]; !ok {
				cloudBrainComputeResource[cloudbrain.Cloudbrain.ComputeResource] = 1
			} else {
				cloudBrainComputeResource[cloudbrain.Cloudbrain.ComputeResource] += 1
			}
		}
		count = len(cloudbrains)
		page += 1
	}

	jobTypeList := []string{string(models.JobTypeDebug), string(models.JobTypeTrain), string(models.JobTypeInference), string(models.JobTypeBenchmark),
		string(models.JobTypeModelSafety), string(models.JobTypeBrainScore), string(models.JobTypeSnn4imagenet), string(models.JobTypeSnn4Ecoset)}
	for _, v := range jobTypeList {
		if _, ok := cloudOneJobTypeRes[v]; !ok {
			cloudOneJobTypeRes[v] = 0
		}
		if _, ok := cloudTwoJobTypeRes[v]; !ok {
			cloudTwoJobTypeRes[v] = 0
		}
		if _, ok := intelligentNetJobTypeRes[v]; !ok {
			intelligentNetJobTypeRes[v] = 0
		}
		if _, ok := cDCenterJobTypeRes[v]; !ok {
			cDCenterJobTypeRes[v] = 0
		}
	}
	cloudBrainTypeList := []int{0, 1, 2, 3}
	for _, v := range cloudBrainTypeList {
		if _, ok := cloudBrainPeriodNum[v]; !ok {
			cloudBrainPeriodNum[v] = 0
		}
	}

	ComputeResourceList := []string{"CPU/GPU", "NPU", "GCU"}
	for _, v := range ComputeResourceList {
		if _, ok := cloudBrainComputeResource[v]; !ok {
			cloudBrainComputeResource[v] = 0
		}
	}

	cloudOneJobTypeRes["EVALUATION"] = cloudBrainPeriodNum[0] - cloudOneJobTypeRes[string(models.JobTypeTrain)] - cloudOneJobTypeRes[string(models.JobTypeInference)] - cloudOneJobTypeRes[string(models.JobTypeDebug)]
	cloudTwoJobTypeRes["EVALUATION"] = cloudBrainPeriodNum[1] - cloudTwoJobTypeRes[string(models.JobTypeTrain)] - cloudTwoJobTypeRes[string(models.JobTypeInference)] - cloudTwoJobTypeRes[string(models.JobTypeDebug)]
	intelligentNetJobTypeRes["EVALUATION"] = cloudBrainPeriodNum[2] - intelligentNetJobTypeRes[string(models.JobTypeTrain)] - intelligentNetJobTypeRes[string(models.JobTypeInference)] - intelligentNetJobTypeRes[string(models.JobTypeDebug)]
	cDCenterJobTypeRes["EVALUATION"] = cloudBrainPeriodNum[3] - cDCenterJobTypeRes[string(models.JobTypeTrain)] - cDCenterJobTypeRes[string(models.JobTypeInference)] - cDCenterJobTypeRes[string(models.JobTypeDebug)]
	ctx.JSON(http.StatusOK, map[string]interface{}{
		"cloudOneJobTypeRes":        cloudOneJobTypeRes,
		"cloudTwoJobTypeRes":        cloudTwoJobTypeRes,
		"intelligentNetJobTypeRes":  intelligentNetJobTypeRes,
		"cDCenterJobTypeRes":        cDCenterJobTypeRes,
		"cloudBrainPeriodNum":       cloudBrainPeriodNum,
		"cloudBrainComputeResource": cloudBrainComputeResource,
	})
}

func GetCloudbrainsStatusAnalysis(ctx *context.Context) {
	cloudbrainStatusCount, err := models.GetCloudbrainStatusCount()
	log.Info("cloudbrainStatusCount:", cloudbrainStatusCount)
	if err != nil {
		log.Error("Can not query cloudbrainStatusCount.", err)
		return
	}

	ctx.JSON(http.StatusOK, map[string]interface{}{
		"cloudbrainStatusCount": cloudbrainStatusCount,
	})
}

func GetCloudbrainsDetailData(ctx *context.Context) {
	recordCloudbrain, err := models.GetRecordBeginTime()
	if err != nil {
		log.Error("Can not get recordCloudbrain", err)
		ctx.Error(http.StatusBadRequest, ctx.Tr("repo.record_begintime_get_err"))
		return
	}
	recordBeginTime := recordCloudbrain[0].Cloudbrain.CreatedUnix
	listType := ctx.Query("listType")
	jobType := ctx.Query("jobType")
	jobStatus := ctx.Query("jobStatus")
	cloudBrainType := ctx.QueryInt("Type")
	aiCenter := ctx.Query("aiCenter")
	needDeleteInfo := ctx.Query("needDeleteInfo")

	accCardType := ctx.Query("accCardType")
	accCardsNum := ctx.QueryInt("accCardsNum")
	workServerNumber := ctx.QueryInt("workServerNumber")
	beginTimeStr := ctx.QueryTrim("beginTime")
	endTimeStr := ctx.QueryTrim("endTime")
	var beginTimeUnix int64
	var endTimeUnix int64
	if beginTimeStr == "" || endTimeStr == "" {
		beginTimeUnix = int64(recordBeginTime)
		endTimeUnix = time.Now().Unix()
	} else {
		beginTime, err := time.ParseInLocation("2006-01-02T15:04:05", beginTimeStr, time.Local)
		if err != nil {
			log.Error("Can not ParseInLocation.", err)
			ctx.Error(http.StatusBadRequest, ctx.Tr("ParseInLocation_get_error"))
			return
		}
		beginTimeUnix = beginTime.Unix()
		endTime, err := time.ParseInLocation("2006-01-02T15:04:05", endTimeStr, time.Local)
		if err != nil {
			log.Error("Can not ParseInLocation.", err)
			ctx.Error(http.StatusBadRequest, ctx.Tr("ParseInLocation_get_error"))
			return
		}
		endTimeUnix = endTime.Unix()
	}

	if cloudBrainType == models.TypeCloudBrainOne && aiCenter == models.AICenterOfCloudBrainOne {
		aiCenter = ""
	}
	if cloudBrainType == models.TypeCloudBrainTwo && aiCenter == models.AICenterOfCloudBrainTwo {
		aiCenter = ""
	}
	if cloudBrainType == models.TypeCDCenter && aiCenter == models.AICenterOfChengdu {
		aiCenter = ""
	}
	if cloudBrainType == models.TypeCloudBrainAll {
		if aiCenter == models.AICenterOfCloudBrainOne {
			cloudBrainType = models.TypeCloudBrainOne
			aiCenter = ""
		}
		if aiCenter == models.AICenterOfCloudBrainTwo {
			cloudBrainType = models.TypeCloudBrainTwo
			aiCenter = ""
		}
		if aiCenter == models.AICenterOfChengdu {
			cloudBrainType = models.TypeCDCenter
			aiCenter = ""
		}
	}

	page := ctx.QueryInt("page")
	pageSize := ctx.QueryInt("pagesize")
	if page <= 0 {
		page = 1
	}
	if pageSize <= 0 {
		pageSize = 10
	}
	var jobTypes []string
	jobTypeNot := false
	if jobType == string(models.JobTypeBenchmark) {
		jobTypes = append(jobTypes, string(models.JobTypeBenchmark), string(models.JobTypeModelSafety), string(models.JobTypeBrainScore), string(models.JobTypeSnn4imagenet), string(models.JobTypeSnn4Ecoset))
	} else if jobType != "all" && jobType != "" {
		jobTypes = append(jobTypes, jobType)
	}

	var jobStatuses []string
	jobStatusNot := false
	if jobStatus == "other" {
		jobStatusNot = true
		jobStatuses = append(jobStatuses, string(models.ModelArtsTrainJobWaiting), string(models.ModelArtsTrainJobFailed), string(models.ModelArtsRunning), string(models.ModelArtsTrainJobCompleted),
			string(models.ModelArtsStarting), string(models.ModelArtsRestarting), string(models.ModelArtsStartFailed),
			string(models.ModelArtsStopping), string(models.ModelArtsStopped), string(models.JobSucceeded))
	} else if jobStatus != "all" && jobStatus != "" {
		jobStatuses = append(jobStatuses, jobStatus)
	}

	keyword := strings.Trim(ctx.Query("q"), " ")

	ciTasks, count, err := models.CloudbrainAll(&models.CloudbrainsOptions{
		ListOptions: models.ListOptions{
			Page:     page,
			PageSize: pageSize,
		},
		Keyword:          keyword,
		Type:             cloudBrainType,
		ComputeResource:  listType,
		JobTypeNot:       jobTypeNot,
		JobStatusNot:     jobStatusNot,
		JobStatus:        jobStatuses,
		JobTypes:         jobTypes,
		NeedRepoInfo:     true,
		BeginTimeUnix:    beginTimeUnix,
		EndTimeUnix:      endTimeUnix,
		AiCenter:         aiCenter,
		NeedDeleteInfo:   needDeleteInfo,
		AccCardType:      accCardType,
		AccCardsNum:      accCardsNum,
		WorkServerNumber: workServerNumber,
	})
	if err != nil {
		ctx.ServerError("Get job failed:", err)
		return
	}
	models.LoadSpecs4CloudbrainInfo(ciTasks)
	nilTime := time.Time{}
	tasks := []models.TaskDetail{}
	for i, task := range ciTasks {
		task = cloudbrainService.UpdateCloudbrainAiCenter(task)
		var taskDetail models.TaskDetail
		taskDetail.ID = ciTasks[i].Cloudbrain.ID
		taskDetail.JobID = ciTasks[i].Cloudbrain.JobID
		taskDetail.JobName = ciTasks[i].JobName
		taskDetail.DisplayJobName = ciTasks[i].DisplayJobName
		taskDetail.Status = ciTasks[i].Status
		taskDetail.JobType = ciTasks[i].JobType
		taskDetail.CreatedUnix = ciTasks[i].Cloudbrain.CreatedUnix
		taskDetail.RunTime = ciTasks[i].Cloudbrain.TrainJobDuration
		taskDetail.StartTime = ciTasks[i].StartTime
		taskDetail.EndTime = ciTasks[i].EndTime
		taskDetail.ComputeResource = ciTasks[i].ComputeResource
		taskDetail.Type = ciTasks[i].Cloudbrain.Type
		taskDetail.UserName = ciTasks[i].User.Name
		taskDetail.RepoID = ciTasks[i].RepoID
		taskDetail.AiCenter = repo.GetAiCenterNameByCode(task.Cloudbrain.AiCenter, ctx.Language())
		if ciTasks[i].Repo != nil {
			taskDetail.RepoName = ciTasks[i].Repo.OwnerName + "/" + ciTasks[i].Repo.Name
			taskDetail.RepoAlias = ciTasks[i].Repo.OwnerName + "/" + ciTasks[i].Repo.Alias
		}
		if ciTasks[i].Cloudbrain.WorkServerNumber >= 1 {
			taskDetail.WorkServerNum = int64(ciTasks[i].Cloudbrain.WorkServerNumber)
		} else {
			taskDetail.WorkServerNum = 1
		}
		taskDetail.CardDuration = repo.GetCloudbrainCardDuration(ciTasks[i].Cloudbrain)
		taskDetail.WaitTime = repo.GetCloudbrainWaitTime(ciTasks[i].Cloudbrain)

		if ciTasks[i].Cloudbrain.DeletedAt != nilTime || ciTasks[i].Repo == nil {
			taskDetail.IsDelete = true
		} else {
			taskDetail.IsDelete = false
		}
		taskDetail.Spec = ciTasks[i].Spec
		tasks = append(tasks, taskDetail)
	}
	pager := context.NewPagination(int(count), pageSize, page, getTotalPage(count, pageSize))
	pager.SetDefaultParams(ctx)
	pager.AddParam(ctx, "listType", "ListType")

	ctx.JSON(http.StatusOK, map[string]interface{}{
		"Title":   ctx.Tr("kanban.cloudBrains"),
		"Tasks":   tasks,
		"Keyword": keyword,
		"pager":   pager,
		"count":   count,
	})
}

func GetCloudbrainsCreateHoursData(ctx *context.Context) {
	recordCloudbrain, err := models.GetRecordBeginTime()
	if err != nil {
		log.Error("Can not get record begin time", err)
		ctx.Error(http.StatusBadRequest, ctx.Tr("repo.record_begintime_get_err"))
		return
	}
	recordBeginTime := time.Unix(int64(recordCloudbrain[0].Cloudbrain.CreatedUnix), 0)
	// recordBeginTime, _ := time.Parse("2006-01-02 15:04:05", recordTime)
	now := time.Now()
	queryType := ctx.QueryTrim("type")
	beginTimeStr := ctx.QueryTrim("beginTime")
	endTimeStr := ctx.QueryTrim("endTime")
	var beginTime time.Time
	var endTime time.Time
	createHourPeriodCount := make(map[string]interface{})
	if queryType != "" {
		if queryType == "all" {
			beginTime = recordBeginTime
			endTime = now.AddDate(0, 0, 1)
			endTime = time.Date(endTime.Year(), endTime.Month(), endTime.Day(), 0, 0, 0, 0, now.Location())
		} else if queryType == "today" {
			beginTime = time.Date(now.Year(), now.Month(), now.Day(), 0, 0, 0, 0, now.Location())
			endTime = now.AddDate(0, 0, 1)
		} else if queryType == "yesterday" {
			beginTime = now.AddDate(0, 0, -1)
			beginTime = time.Date(beginTime.Year(), beginTime.Month(), beginTime.Day(), 0, 0, 0, 0, now.Location())
			endTime = time.Date(now.Year(), now.Month(), now.Day(), 0, 0, 0, 0, now.Location())
		} else if queryType == "current_week" {
			beginTime = now.AddDate(0, 0, -int(time.Now().Weekday())+1) //begin from monday
			endTime = now
		} else if queryType == "current_month" {
			beginTime = time.Date(now.Year(), now.Month(), 1, 0, 0, 0, 0, now.Location())
			endTime = now.AddDate(0, 0, 1)
			endTime = time.Date(endTime.Year(), endTime.Month(), endTime.Day(), 0, 0, 0, 0, now.Location())
		} else if queryType == "monthly" {
			endTime = now
			beginTime = now.AddDate(0, -1, 0)
			beginTime = time.Date(beginTime.Year(), beginTime.Month(), beginTime.Day(), 0, 0, 0, 0, now.Location())
		} else if queryType == "current_year" {
			beginTime = time.Date(now.Year(), 1, 1, 0, 0, 0, 0, now.Location())
			endTime = now.AddDate(0, 0, 1)
			endTime = time.Date(endTime.Year(), endTime.Month(), endTime.Day(), 0, 0, 0, 0, now.Location())
		} else if queryType == "last_month" {
			lastMonthTime := now.AddDate(0, -1, 0)
			beginTime = time.Date(lastMonthTime.Year(), lastMonthTime.Month(), 1, 0, 0, 0, 0, now.Location())
			endTime = time.Date(now.Year(), now.Month(), 1, 0, 0, 0, 0, now.Location())
		} else if queryType == "last_7day" {
			beginTime = now.AddDate(0, 0, -6)
			beginTime = time.Date(beginTime.Year(), beginTime.Month(), beginTime.Day(), 0, 0, 0, 0, now.Location())
			endTime = now.AddDate(0, 0, 1)
			endTime = time.Date(endTime.Year(), endTime.Month(), endTime.Day(), 0, 0, 0, 0, now.Location())
		} else if queryType == "last_30day" {
			beginTime = now.AddDate(0, 0, -29)
			beginTime = time.Date(beginTime.Year(), beginTime.Month(), beginTime.Day(), 0, 0, 0, 0, now.Location())
			endTime = now.AddDate(0, 0, 1)
			endTime = time.Date(endTime.Year(), endTime.Month(), endTime.Day(), 0, 0, 0, 0, now.Location())
		}
	} else {
		if beginTimeStr == "" || endTimeStr == "" {
			//如果查询类型和开始时间结束时间都未设置，按queryType=all处理
			beginTime = recordBeginTime
			endTime = now.AddDate(0, 0, 1)
			endTime = time.Date(endTime.Year(), endTime.Month(), endTime.Day(), 0, 0, 0, 0, now.Location())
		} else {
			beginTime, err = time.ParseInLocation("2006-01-02", beginTimeStr, time.Local)
			if err != nil {
				log.Error("Can not ParseInLocation.", err)
				ctx.Error(http.StatusBadRequest, ctx.Tr("ParseInLocation_get_error"))
				return
			}
			endTime, err = time.ParseInLocation("2006-01-02", endTimeStr, time.Local)
			if err != nil {
				log.Error("Can not ParseInLocation.", err)
				ctx.Error(http.StatusBadRequest, ctx.Tr("ParseInLocation_get_error"))
				return
			}
			endTime = time.Date(endTime.Year(), endTime.Month(), endTime.Day(), 0, 0, 0, 0, now.Location())
		}
	}
	dateBeginTime := beginTime.Format("2006-01-02")
	dateEndTime := endTime.Format("2006-01-02")
	createHourPeriodCount, err = models.GetCreateHourPeriodCount(dateBeginTime, dateEndTime)
	if err != nil {
		log.Error("Can not query hourPeriodCount.", err)
		ctx.Error(http.StatusBadRequest, ctx.Tr("hourPeriodCount_get_error"))
		return
	}

	runHourPeriodCount, err := models.GetRunHourPeriodCount(dateBeginTime, dateEndTime)
	if err != nil {
		log.Error("Can not query runHourPeriodCount.", err)
		ctx.Error(http.StatusBadRequest, ctx.Tr("runHourPeriodCount_get_error"))
		return
	}
	ctx.JSON(http.StatusOK, map[string]interface{}{
		"recordBeginTime":       recordCloudbrain[0].Cloudbrain.CreatedUnix,
		"updateTime":            now.Unix(),
		"createHourPeriodCount": createHourPeriodCount,
		"runHourPeriodCount":    runHourPeriodCount,
	})

}
func GetWaittingTop(ctx *context.Context) {
	ciTasks, err := models.GetWaittingTop()
	if err != nil {
		log.Error("Can not get record begin time", err)
		ctx.Error(http.StatusBadRequest, ctx.Tr("repo.record_begintime_get_err"))
		return
	}
	tasks := []models.TaskDetail{}
	for i, task := range ciTasks {
		ciTasks[i].Cloudbrain.ComputeResource = task.ComputeResource

		var taskDetail models.TaskDetail
		taskDetail.DisplayJobName = ciTasks[i].DisplayJobName
		taskDetail.UserName = ciTasks[i].User.Name
		taskDetail.RepoID = ciTasks[i].RepoID
		if ciTasks[i].Repo != nil {
			taskDetail.RepoName = ciTasks[i].Repo.OwnerName + "/" + ciTasks[i].Repo.Name
		} else {
			taskDetail.RepoName = ""
		}
		WaitTimeInt := time.Now().Unix() - ciTasks[i].Cloudbrain.CreatedUnix.AsTime().Unix()
		taskDetail.WaitTime = models.ConvertDurationToStr(WaitTimeInt)

		if WaitTimeInt < 0 {
			taskDetail.WaitTime = "00:00:00"
		}

		taskDetail.ID = ciTasks[i].Cloudbrain.ID
		taskDetail.ComputeResource = ciTasks[i].Cloudbrain.ComputeResource
		taskDetail.JobType = ciTasks[i].Cloudbrain.JobType
		taskDetail.JobID = ciTasks[i].Cloudbrain.JobID
		taskDetail.Type = ciTasks[i].Cloudbrain.Type

		tasks = append(tasks, taskDetail)
	}
	ctx.JSON(http.StatusOK, map[string]interface{}{
		"tasks": tasks,
	})
}
func GetRunningTop(ctx *context.Context) {
	ciTasks, err := models.GetRunningTop()
	if err != nil {
		log.Error("Can not get record begin time", err)
		ctx.Error(http.StatusBadRequest, ctx.Tr("repo.record_begintime_get_err"))
		return
	}
	tasks := []models.TaskDetail{}
	for i, task := range ciTasks {
		ciTasks[i].Cloudbrain.ComputeResource = task.ComputeResource

		var taskDetail models.TaskDetail
		taskDetail.DisplayJobName = ciTasks[i].DisplayJobName
		taskDetail.RunTime = ciTasks[i].Cloudbrain.TrainJobDuration
		taskDetail.UserName = ciTasks[i].User.Name
		taskDetail.RepoID = ciTasks[i].RepoID
		if ciTasks[i].Repo != nil {
			taskDetail.RepoName = ciTasks[i].Repo.OwnerName + "/" + ciTasks[i].Repo.Name
		}

		taskDetail.ID = ciTasks[i].Cloudbrain.ID
		taskDetail.ComputeResource = ciTasks[i].Cloudbrain.ComputeResource
		taskDetail.JobType = ciTasks[i].Cloudbrain.JobType
		taskDetail.JobID = ciTasks[i].Cloudbrain.JobID
		taskDetail.Type = ciTasks[i].Cloudbrain.Type

		tasks = append(tasks, taskDetail)
	}
	ctx.JSON(http.StatusOK, map[string]interface{}{
		"tasks": tasks,
	})
}

func getCloudbrainCount(beginTime time.Time, endTime time.Time, cloudbrains []*models.CloudbrainInfo) (map[string]int, map[string]int, map[string]int, map[string]int, map[int]int, map[string]int) {

	cloudOneJobTypeRes := make(map[string]int)
	cloudTwoJobTypeRes := make(map[string]int)
	intelligentNetJobTypeRes := make(map[string]int)
	cDCenterJobTypeRes := make(map[string]int)
	cloudBrainPeriodNum := make(map[int]int)
	cloudBrainComputeResource := make(map[string]int)
	for _, cloudbrain := range cloudbrains {
		if int64(cloudbrain.Cloudbrain.CreatedUnix) >= beginTime.Unix() && int64(cloudbrain.Cloudbrain.CreatedUnix) < endTime.Unix() {
			if cloudbrain.Cloudbrain.Type == models.TypeCloudBrainOne {
				if _, ok := cloudOneJobTypeRes[cloudbrain.Cloudbrain.JobType]; !ok {
					cloudOneJobTypeRes[cloudbrain.Cloudbrain.JobType] = 1
				} else {
					cloudOneJobTypeRes[cloudbrain.Cloudbrain.JobType] += 1
				}
			}
			if cloudbrain.Cloudbrain.Type == models.TypeCloudBrainTwo {
				if _, ok := cloudTwoJobTypeRes[cloudbrain.JobType]; !ok {
					cloudTwoJobTypeRes[cloudbrain.Cloudbrain.JobType] = 1
				} else {
					cloudTwoJobTypeRes[cloudbrain.Cloudbrain.JobType] += 1
				}
			}

			if _, ok := cloudBrainPeriodNum[cloudbrain.Cloudbrain.Type]; !ok {
				cloudBrainPeriodNum[cloudbrain.Cloudbrain.Type] = 1
			} else {
				cloudBrainPeriodNum[cloudbrain.Cloudbrain.Type] += 1
			}

			if _, ok := cloudBrainComputeResource[cloudbrain.Cloudbrain.ComputeResource]; !ok {
				cloudBrainComputeResource[cloudbrain.Cloudbrain.ComputeResource] = 1
			} else {
				cloudBrainComputeResource[cloudbrain.Cloudbrain.ComputeResource] += 1
			}

		}
	}

	ComputeResourceList := []string{"CPU/GPU", "NPU", "GCU"}
	for _, v := range ComputeResourceList {
		if _, ok := cloudBrainComputeResource[v]; !ok {
			cloudBrainComputeResource[v] = 0
		}
	}

	jobTypeList := []string{"DEBUG", "BENCHMARK", "INFERENCE", "TRAIN", "SNN4IMAGENET", "BRAINSCORE"}
	cloudBrainTypeList := []int{0, 1, 2, 3}
	for _, v := range jobTypeList {
		if _, ok := cloudOneJobTypeRes[v]; !ok {
			cloudOneJobTypeRes[v] = 0
		}
		if _, ok := cloudTwoJobTypeRes[v]; !ok {
			cloudTwoJobTypeRes[v] = 0
		}
		if _, ok := intelligentNetJobTypeRes[v]; !ok {
			intelligentNetJobTypeRes[v] = 0
		}
		if _, ok := cDCenterJobTypeRes[v]; !ok {
			cDCenterJobTypeRes[v] = 0
		}
	}
	for _, v := range cloudBrainTypeList {
		if _, ok := cloudBrainPeriodNum[v]; !ok {
			cloudBrainPeriodNum[v] = 0
		}
	}
	cloudBrainPeriodNum[-1] = cloudBrainPeriodNum[0] + cloudBrainPeriodNum[1] + cloudBrainPeriodNum[2] + cloudBrainPeriodNum[3]
	return cloudOneJobTypeRes, cloudTwoJobTypeRes, intelligentNetJobTypeRes, cDCenterJobTypeRes, cloudBrainPeriodNum, cloudBrainComputeResource
}

func getDayCloudbrainNum(beginTime time.Time, endTime time.Time) ([]DateCloudbrainNum, error) {
	var endTimeTemp time.Time
	endTimeTemp = beginTime.AddDate(0, 0, 1)
	cloudbrains, _, err := models.CloudbrainAllStatic(&models.CloudbrainsOptions{
		Type:          models.TypeCloudBrainAll,
		BeginTimeUnix: beginTime.Unix(),
		EndTimeUnix:   endTime.Unix(),
	})
	if err != nil {
		log.Error("Get cloudbrains failed:", err)
		return nil, err
	}
	dayCloudbrainNum := make([]DateCloudbrainNum, 0)
	for endTimeTemp.Before(endTime) || endTimeTemp.Equal(endTime) {
		cloudOneJobTypeRes, cloudTwoJobTypeRes, intelligentNetJobTypeRes, cDCenterJobTypeRes, cloudBrainPeriodNum, cloudBrainComputeResource := getCloudbrainCount(beginTime, endTimeTemp, cloudbrains)
		dayCloudbrainNum = append(dayCloudbrainNum, DateCloudbrainNum{
			Date:                      beginTime.Format("2006/01/02"),
			CloudOneJobTypeRes:        cloudOneJobTypeRes,
			CloudTwoJobTypeRes:        cloudTwoJobTypeRes,
			IntelligentNetJobTypeRes:  intelligentNetJobTypeRes,
			CDCenterJobTypeRes:        cDCenterJobTypeRes,
			CloudBrainPeriodNum:       cloudBrainPeriodNum,
			CloudBrainComputeResource: cloudBrainComputeResource,
		})
		if endTime.Before(endTimeTemp.AddDate(0, 0, 1)) && endTimeTemp.Before(endTime) {
			beginTime = endTimeTemp
			endTimeTemp = endTime
		} else {
			beginTime = endTimeTemp
			endTimeTemp = beginTime.AddDate(0, 0, 1)
		}
	}
	return dayCloudbrainNum, nil
}
func getMonthCloudbrainNum(beginTime time.Time, endTime time.Time) ([]DateCloudbrainNum, error) {
	var endTimeTemp time.Time
	now := time.Now()
	endTimeTemp = beginTime.AddDate(0, 1, 0)
	endTimeTemp = time.Date(endTimeTemp.Year(), endTimeTemp.Month(), 1, 0, 0, 0, 0, now.Location())
	monthCloudbrainNum := make([]DateCloudbrainNum, 0)
	cloudbrains, _, err := models.CloudbrainAllStatic(&models.CloudbrainsOptions{
		Type:          models.TypeCloudBrainAll,
		BeginTimeUnix: beginTime.Unix(),
		EndTimeUnix:   endTime.Unix(),
	})
	if err != nil {
		log.Error("Getcloudbrains failed:%v", err)
		return nil, err
	}
	for endTimeTemp.Before(endTime) || endTimeTemp.Equal(endTime) {
		cloudOneJobTypeRes, cloudTwoJobTypeRes, intelligentNetJobTypeRes, cDCenterJobTypeRes, cloudBrainPeriodNum, cloudBrainComputeResource := getCloudbrainCount(beginTime, endTimeTemp, cloudbrains)
		monthCloudbrainNum = append(monthCloudbrainNum, DateCloudbrainNum{
			Date:                      beginTime.Format("2006/01"),
			CloudOneJobTypeRes:        cloudOneJobTypeRes,
			CloudTwoJobTypeRes:        cloudTwoJobTypeRes,
			IntelligentNetJobTypeRes:  intelligentNetJobTypeRes,
			CDCenterJobTypeRes:        cDCenterJobTypeRes,
			CloudBrainPeriodNum:       cloudBrainPeriodNum,
			CloudBrainComputeResource: cloudBrainComputeResource,
		})
		if endTime.Before(endTimeTemp.AddDate(0, 1, 0)) && endTimeTemp.Before(endTime) {
			beginTime = endTimeTemp
			endTimeTemp = endTime
		} else {
			beginTime = endTimeTemp
			endTimeTemp = beginTime.AddDate(0, 1, 0)
		}
	}
	return monthCloudbrainNum, nil
}

func getDayCloudbrainInfo(beginTime time.Time, endTime time.Time) ([]DateCloudbrainInfo, int, error) {
	now := time.Now()
	endTimeTemp := time.Date(endTime.Year(), endTime.Month(), endTime.Day(), 0, 0, 0, 0, now.Location())
	if endTimeTemp.Equal(endTime) {
		endTimeTemp = endTimeTemp.AddDate(0, 0, -1)
	}
	cloudbrains, _, err := models.CloudbrainAllStatic(&models.CloudbrainsOptions{
		Type:          models.TypeCloudBrainAll,
		BeginTimeUnix: beginTime.Unix(),
		EndTimeUnix:   endTime.Unix(),
	})
	if err != nil {
		log.Error("Getcloudbrains failed:%v", err)
		return nil, 0, err
	}
	dayCloudbrainInfo := make([]DateCloudbrainInfo, 0)
	count := 0
	for beginTime.Before(endTimeTemp) || beginTime.Equal(endTimeTemp) {
		_, _, _, _, cloudBrainPeriodNum, cloudBrainComputeResource := getCloudbrainCount(endTimeTemp, endTime, cloudbrains)
		dayCloudbrainInfo = append(dayCloudbrainInfo, DateCloudbrainInfo{
			Date:                      endTimeTemp.Format("2006/01/02"),
			CloudBrainPeriodNum:       cloudBrainPeriodNum,
			CloudBrainComputeResource: cloudBrainComputeResource,
		})
		endTime = endTimeTemp
		endTimeTemp = endTimeTemp.AddDate(0, 0, -1)
		count += 1
	}
	return dayCloudbrainInfo, count, nil
}

func getMonthCloudbrainInfo(beginTime time.Time, endTime time.Time) ([]DateCloudbrainInfo, int, error) {
	now := time.Now()
	endTimeTemp := time.Date(endTime.Year(), endTime.Month(), 1, 0, 0, 0, 0, now.Location())
	if endTimeTemp.Equal(endTime) {
		endTimeTemp = endTimeTemp.AddDate(0, -1, 0)
	}
	cloudbrains, _, err := models.CloudbrainAllStatic(&models.CloudbrainsOptions{
		Type:          models.TypeCloudBrainAll,
		BeginTimeUnix: beginTime.Unix(),
		EndTimeUnix:   endTime.Unix(),
	})
	if err != nil {
		log.Error("Getcloudbrains failed:%v", err)
		return nil, 0, err
	}
	dayCloudbrainInfo := make([]DateCloudbrainInfo, 0)
	count := 0
	for beginTime.Before(endTimeTemp) || beginTime.Equal(endTimeTemp) || (endTimeTemp.Before(beginTime) && beginTime.Before(endTime)) {
		_, _, _, _, cloudBrainPeriodNum, cloudBrainComputeResource := getCloudbrainCount(endTimeTemp, endTime, cloudbrains)
		dayCloudbrainInfo = append(dayCloudbrainInfo, DateCloudbrainInfo{
			Date:                      endTimeTemp.Format("2006/01"),
			CloudBrainPeriodNum:       cloudBrainPeriodNum,
			CloudBrainComputeResource: cloudBrainComputeResource,
		})
		endTime = endTimeTemp
		endTimeTemp = endTimeTemp.AddDate(0, -1, 0)
		count += 1
	}
	return dayCloudbrainInfo, count, nil
}

func DownloadCloudBrainBoard(ctx *context.Context) {
	recordCloudbrain, err := models.GetRecordBeginTime()
	if err != nil {
		log.Error("Can not get recordCloudbrain", err)
		ctx.Error(http.StatusBadRequest, ctx.Tr("repo.record_begintime_get_err"))
		return
	}

	page := 1

	pageSize := 300

	var cloudBrain = ctx.Tr("repo.cloudbrain")
	fileName := getCloudbrainFileName(cloudBrain)

	recordBeginTime := recordCloudbrain[0].Cloudbrain.CreatedUnix
	now := time.Now()
	endTime := now

	_, total, err := models.CloudbrainAll(&models.CloudbrainsOptions{
		ListOptions: models.ListOptions{
			Page:     page,
			PageSize: pageSize,
		},
		Type:          models.TypeCloudBrainAll,
		BeginTimeUnix: int64(recordBeginTime),
		EndTimeUnix:   endTime.Unix(),
		AccCardsNum:   models.AccCardsNumAll,
	})

	if err != nil {
		log.Warn("Can not get cloud brain info", err)
		ctx.Error(http.StatusBadRequest, ctx.Tr("repo.cloudbrain_query_fail"))
		return
	}
	totalPage := getTotalPage(total, pageSize)
	f := excelize.NewFile()

	index := f.NewSheet(cloudBrain)
	f.DeleteSheet("Sheet1")

	for k, v := range allCloudbrainHeader(ctx) {
		f.SetCellValue(cloudBrain, k, v)
	}

	var row = 2
	for i := 0; i < totalPage; i++ {

		pageRecords, _, err := models.CloudbrainAll(&models.CloudbrainsOptions{
			ListOptions: models.ListOptions{
				Page:     page,
				PageSize: pageSize,
			},
			Type:          models.TypeCloudBrainAll,
			BeginTimeUnix: int64(recordBeginTime),
			EndTimeUnix:   endTime.Unix(),
			NeedRepoInfo:  true,
			AccCardsNum:   models.AccCardsNumAll,
		})
		if err != nil {
			log.Warn("Can not get cloud brain info", err)
			continue
		}
		models.LoadSpecs4CloudbrainInfo(pageRecords)
		for _, record := range pageRecords {
			record = cloudbrainService.UpdateCloudbrainAiCenter(record)
			record.Cloudbrain.AiCenter = repo.GetAiCenterNameByCode(record.Cloudbrain.AiCenter, ctx.Language())
			for k, v := range allCloudbrainValues(row, record, ctx) {
				f.SetCellValue(cloudBrain, k, v)
			}
			row++

		}

		page++
	}
	f.SetActiveSheet(index)

	ctx.Resp.Header().Set("Content-Disposition", "attachment; filename="+url.QueryEscape(fileName))
	ctx.Resp.Header().Set("Content-Type", "application/octet-stream")

	f.WriteTo(ctx.Resp)
}

func getCloudbrainFileName(baseName string) string {
	return baseName + "_" + time.Now().Format(EXCEL_DATE_FORMAT) + ".xlsx"

}
func allCloudbrainHeader(ctx *context.Context) map[string]string {

	return map[string]string{"A1": ctx.Tr("repo.cloudbrain_task"), "B1": ctx.Tr("repo.cloudbrain_type"), "C1": ctx.Tr("repo.modelarts.status"), "D1": ctx.Tr("repo.cloudbrain_task_type"),
		"E1": ctx.Tr("repo.modelarts.createtime"), "F1": ctx.Tr("repo.modelarts.train_job.wait_time"), "G1": ctx.Tr("repo.modelarts.train_job.dura_time"),
		"H1": ctx.Tr("cloudbrain.card_duration"),
		"I1": ctx.Tr("repo.modelarts.train_job.start_time"), "J1": ctx.Tr("repo.modelarts.train_job.end_time"),
		"K1": ctx.Tr("repo.modelarts.computing_resources"), "L1": ctx.Tr("cloudbrain.card_type"),
		"M1": ctx.Tr("repo.modelarts.train_job.amount_of_compute_node"), "N1": ctx.Tr("repo.grampus.train_job.ai_center"),
		"O1": ctx.Tr("cloudbrain.resource_specification"), "P1": ctx.Tr("repo.cloudbrain_creator"), "Q1": ctx.Tr("repo.repo_name"),
		"R1": ctx.Tr("repo.cloudbrain_task_name"), "S1": ctx.Tr("repo.modelarts.deletetime")}
}
func allCloudbrainValues(row int, rs *models.CloudbrainInfo, ctx *context.Context) map[string]string {
	return map[string]string{getCellName("A", row): rs.DisplayJobName, getCellName("B", row): getCloudbrainType(rs, ctx), getCellName("C", row): rs.Status, getCellName("D", row): rs.JobType,
		getCellName("E", row): time.Unix(int64(rs.Cloudbrain.CreatedUnix), 0).Format(CREATE_TIME_FORMAT), getCellName("F", row): repo.GetCloudbrainWaitTime(rs.Cloudbrain),
		getCellName("G", row): rs.TrainJobDuration, getCellName("H", row): repo.GetCloudbrainCardDuration(rs.Cloudbrain),
		getCellName("I", row): getBrainStartTime(rs),
		getCellName("J", row): getBrainEndTime(rs), getCellName("K", row): rs.ComputeResource, getCellName("L", row): getCloudbrainCardType(rs),
		getCellName("M", row): getWorkServerNum(rs), getCellName("N", row): rs.Cloudbrain.AiCenter,
		getCellName("O", row): getCloudbrainFlavorName(rs), getCellName("P", row): rs.Name,
		getCellName("Q", row): getBrainRepo(rs), getCellName("R", row): rs.JobName, getCellName("S", row): getBrainDeleteTime(rs),
	}
}
func getWorkServerNum(rs *models.CloudbrainInfo) string {
	if rs.Cloudbrain.WorkServerNumber >= 1 {
		return fmt.Sprint(rs.Cloudbrain.WorkServerNumber)
	} else {
		return "1"
	}
}
func getBrainRepo(rs *models.CloudbrainInfo) string {
	if rs.Repo != nil {
		return rs.Repo.OwnerName + "/" + rs.Repo.Alias
	}
	return ""
}
func getBrainStartTime(rs *models.CloudbrainInfo) string {
	timeString := time.Unix(int64(rs.Cloudbrain.StartTime), 0).Format(CREATE_TIME_FORMAT)
	if timeString != "1970/01/01 08:00:00" {
		return timeString
	} else {
		return "0"
	}

}
func getBrainEndTime(rs *models.CloudbrainInfo) string {
	timeString := time.Unix(int64(rs.Cloudbrain.EndTime), 0).Format(CREATE_TIME_FORMAT)
	if timeString != "1970/01/01 08:00:00" {
		return timeString
	} else {
		return "0"
	}

}
func getCloudbrainType(rs *models.CloudbrainInfo, ctx *context.Context) string {
	if rs.Cloudbrain.Type == models.TypeCloudBrainOne {
		return ctx.Tr("repo.cloudbrain1")
	} else if rs.Cloudbrain.Type == models.TypeCloudBrainTwo {
		return ctx.Tr("repo.cloudbrain2")
	} else if rs.Cloudbrain.Type == models.TypeC2Net {
		return ctx.Tr("repo.intelligent_net")
	} else {
		return ctx.Tr("repo.cloudbrain_untype")
	}
}
func getCloudbrainCardType(rs *models.CloudbrainInfo) string {
	if rs.Cloudbrain.Spec != nil {
		return rs.Cloudbrain.Spec.AccCardType
	} else {
		return ""
	}
}
func getCloudbrainFlavorName(rs *models.CloudbrainInfo) string {
	flavorName := repo.GetCloudbrainFlavorName(rs.Cloudbrain)
	return flavorName
}

func getBrainDeleteTime(rs *models.CloudbrainInfo) string {
	nilTime := time.Time{}
	if rs.Cloudbrain.DeletedAt != nilTime {
		return rs.Cloudbrain.DeletedAt.Format("2006-01-02 15:04:05")
	} else {
		return ""
	}
}
func getCloudbrainTimePeroid(ctx *context.Context, recordBeginTime time.Time) (time.Time, time.Time, error) {
	queryType := ctx.QueryTrim("type")
	beginTimeStr := ctx.QueryTrim("beginTime")
	endTimeStr := ctx.QueryTrim("endTime")
	now := time.Now()

	var beginTime time.Time
	var endTime time.Time
	var err error
	if queryType != "" {

		if queryType == "all" {
			beginTime = recordBeginTime
			endTime = now
		} else if queryType == "today" {
			endTime = now
			beginTime = time.Date(endTime.Year(), endTime.Month(), endTime.Day(), 0, 0, 0, 0, now.Location())
		} else if queryType == "yesterday" {
			endTime = time.Date(now.Year(), now.Month(), now.Day(), 0, 0, 0, 0, now.Location())
			beginTime = endTime.AddDate(0, 0, -1)

		} else if queryType == "last_7day" {
			beginTime = now.AddDate(0, 0, -6)
			beginTime = time.Date(beginTime.Year(), beginTime.Month(), beginTime.Day(), 0, 0, 0, 0, now.Location())
			endTime = now
		} else if queryType == "last_30day" {
			beginTime = now.AddDate(0, 0, -29)
			beginTime = time.Date(beginTime.Year(), beginTime.Month(), beginTime.Day(), 0, 0, 0, 0, now.Location())
			endTime = now
		} else if queryType == "current_month" {
			endTime = now
			beginTime = time.Date(endTime.Year(), endTime.Month(), 1, 0, 0, 0, 0, now.Location())
		} else if queryType == "monthly" {
			endTime = now
			beginTime = now.AddDate(0, -1, 1)
			beginTime = time.Date(beginTime.Year(), beginTime.Month(), beginTime.Day(), 0, 0, 0, 0, now.Location())

		} else if queryType == "current_year" {
			endTime = now
			beginTime = time.Date(endTime.Year(), 1, 1, 0, 0, 0, 0, now.Location())

		} else if queryType == "last_month" {

			lastMonthTime := now.AddDate(0, -1, 0)
			beginTime = time.Date(lastMonthTime.Year(), lastMonthTime.Month(), 1, 0, 0, 0, 0, now.Location())
			endTime = time.Date(now.Year(), now.Month(), 1, 0, 0, 0, 0, now.Location())

		} else {
			return now, now, fmt.Errorf("The value of type parameter is wrong.")

		}

	} else {
		if beginTimeStr == "" || endTimeStr == "" {
			//如果查询类型和开始时间结束时间都未设置，按queryType=all处理
			beginTime = recordBeginTime
			endTime = now

		} else {

			beginTime, err = time.ParseInLocation("2006-01-02", beginTimeStr, time.Local)
			if err != nil {
				return now, now, err
			}

			endTime, err = time.ParseInLocation("2006-01-02", endTimeStr, time.Local)
			if err != nil {
				return now, now, err
			}
		}

	}

	if beginTime.Before(recordBeginTime) {
		beginTime = recordBeginTime
	}

	return beginTime, endTime, nil
}

func GetCloudbrainResourceOverview(ctx *context.Context) {
	var recordBeginTime timeutil.TimeStamp
	recordCloudbrainDuration, err := models.GetDurationRecordBeginTime()
	if err != nil {
		log.Error("Can not get GetDurationRecordBeginTime", err)
		return
	}
	if len(recordCloudbrainDuration) > 0 && err == nil {
		recordBeginTime = recordCloudbrainDuration[0].DateTimeUnix
	} else {
		recordBeginTime = timeutil.TimeStamp(time.Now().Unix())
	}
	recordUpdateTime := time.Now().Unix()
	resourceQueues, err := models.GetCanUseCardInfo()
	if err != nil {
		log.Info("GetCanUseCardInfo err: %v", err)
		return
	}
	OpenIResourceDetail := []models.ResourceDetail{}
	C2NetResourceDetail := []models.ResourceDetail{}
	for _, resourceQueue := range resourceQueues {
		if resourceQueue.Cluster == models.OpenICluster {
			aiCenterName := repo.GetAiCenterNameByCode(resourceQueue.AiCenterCode, ctx.Language())
			var resourceDetail models.ResourceDetail
			resourceDetail.QueueCode = resourceQueue.QueueCode
			resourceDetail.Cluster = resourceQueue.Cluster
			resourceDetail.AiCenterCode = resourceQueue.AiCenterCode
			resourceDetail.AiCenterName = resourceQueue.AiCenterCode + "/" + aiCenterName
			resourceDetail.ComputeResource = resourceQueue.ComputeResource
			resourceDetail.AccCardType = resourceQueue.AccCardType + "(" + resourceQueue.ComputeResource + ")"
			resourceDetail.CardsTotalNum = resourceQueue.CardsTotalNum
			resourceDetail.IsAutomaticSync = resourceQueue.IsAutomaticSync
			OpenIResourceDetail = append(OpenIResourceDetail, resourceDetail)
		}
		if resourceQueue.Cluster == models.C2NetCluster {
			aiCenterName := repo.GetAiCenterNameByCode(resourceQueue.AiCenterCode, ctx.Language())
			var resourceDetail models.ResourceDetail
			resourceDetail.QueueCode = resourceQueue.QueueCode
			resourceDetail.Cluster = resourceQueue.Cluster
			resourceDetail.AiCenterCode = resourceQueue.AiCenterCode
			resourceDetail.AiCenterName = resourceQueue.AiCenterCode + "/" + aiCenterName
			resourceDetail.ComputeResource = resourceQueue.ComputeResource
			resourceDetail.AccCardType = resourceQueue.AccCardType + "(" + resourceQueue.ComputeResource + ")"
			resourceDetail.CardsTotalNum = resourceQueue.CardsTotalNum
			resourceDetail.IsAutomaticSync = resourceQueue.IsAutomaticSync
			C2NetResourceDetail = append(C2NetResourceDetail, resourceDetail)
		}
	}
	openIResourceNum := make(map[string]map[string]int)

	for _, openIResourceDetail := range OpenIResourceDetail {
		if _, ok := openIResourceNum[openIResourceDetail.AiCenterName]; !ok {
			openIResourceNum[openIResourceDetail.AiCenterName] = make(map[string]int)
		}
		if _, ok := openIResourceNum[openIResourceDetail.AiCenterName][openIResourceDetail.AccCardType]; !ok {
			openIResourceNum[openIResourceDetail.AiCenterName][openIResourceDetail.AccCardType] = openIResourceDetail.CardsTotalNum
		} else {
			openIResourceNum[openIResourceDetail.AiCenterName][openIResourceDetail.AccCardType] += openIResourceDetail.CardsTotalNum
		}
	}

	c2NetResourceNum := make(map[string]map[string]int)
	for _, c2NetResourceDetail := range C2NetResourceDetail {
		if _, ok := c2NetResourceNum[c2NetResourceDetail.AiCenterName]; !ok {
			c2NetResourceNum[c2NetResourceDetail.AiCenterName] = make(map[string]int)
		}
		if _, ok := c2NetResourceNum[c2NetResourceDetail.AiCenterName][c2NetResourceDetail.AccCardType]; !ok {
			c2NetResourceNum[c2NetResourceDetail.AiCenterName][c2NetResourceDetail.AccCardType] = c2NetResourceDetail.CardsTotalNum
		} else {
			c2NetResourceNum[c2NetResourceDetail.AiCenterName][c2NetResourceDetail.AccCardType] += c2NetResourceDetail.CardsTotalNum
		}

	}

	ctx.JSON(http.StatusOK, map[string]interface{}{
		"openI":            openIResourceNum,
		"c2Net":            c2NetResourceNum,
		"recordUpdateTime": recordUpdateTime,
		"recordBeginTime":  recordBeginTime,
	})
}

func GetCloudbrainResourceUsageDetail(ctx *context.Context) {
	aiCenterCode := ctx.QueryTrim("aiCenterCode")
	if aiCenterCode == "" {
		aiCenterCode = models.AICenterOfCloudBrainOne
	}
	beginTime, endTime := getBeginAndEndTime(ctx)
	dayCloudbrainDuration, count, err := getDayCloudbrainDuration(beginTime, endTime, aiCenterCode)
	if err != nil {
		log.Error("Can not query dayCloudbrainDuration.", err)
		return
	}
	hourCloudbrainDuration, err := getHourCloudbrainDuration(beginTime, endTime, aiCenterCode)
	if err != nil {
		log.Error("Can not query hourCloudbrainDuration.", err)
		return
	}
	page := ctx.QueryInt("page")
	if page <= 0 {
		page = 1
	}
	pagesize := ctx.QueryInt("pagesize")
	if pagesize <= 0 {
		pagesize = 36500
	}
	pageDateCloudbrainDuration := getPageDateCloudbrainDuration(dayCloudbrainDuration, page, pagesize)
	ctx.JSON(http.StatusOK, map[string]interface{}{
		"totalCount":                 count,
		"pageDateCloudbrainDuration": pageDateCloudbrainDuration,
		"hourCloudbrainDuration":     hourCloudbrainDuration,
	})
}

func GetDurationRateStatistic(ctx *context.Context) {
	beginTime, endTime := getBeginAndEndTime(ctx)
	OpenIDurationRate, C2NetDurationRate, totalUsageRate := getDurationStatistic(beginTime, endTime)

	ctx.JSON(http.StatusOK, map[string]interface{}{
		"openIDurationRate": OpenIDurationRate,
		"c2NetDurationRate": C2NetDurationRate,
		"totalUsageRate":    totalUsageRate,
	})

}

func CloudbrainDurationStatisticForTest(ctx *context.Context) {
	repo.CloudbrainDurationStatisticHour()
	ctx.JSON(http.StatusOK, map[string]interface{}{
		"message": 0,
	})
}

func getBeginAndEndTime(ctx *context.Context) (time.Time, time.Time) {
	queryType := ctx.QueryTrim("type")
	now := time.Now()
	beginTimeStr := ctx.QueryTrim("beginTime")
	endTimeStr := ctx.QueryTrim("endTime")
	var brainRecordBeginTime time.Time

	var beginTime time.Time
	var endTime time.Time
	var err error
	if queryType != "" {
		if queryType == "all" {
			recordCloudbrainDuration, err := models.GetDurationRecordBeginTime()
			if err != nil {
				log.Error("Can not get GetDurationRecordBeginTime", err)
				ctx.Error(http.StatusBadRequest, ctx.Tr("repo.record_begintime_get_err"))
				return beginTime, endTime
			}
			if len(recordCloudbrainDuration) > 0 && err == nil {
				brainRecordBeginTime = recordCloudbrainDuration[0].DateTimeUnix.AsTime()
			} else {
				brainRecordBeginTime = now
			}

			beginTime = brainRecordBeginTime
			endTime = now
		} else if queryType == "today" {
			beginTime = now.AddDate(0, 0, 0)
			beginTime = time.Date(beginTime.Year(), beginTime.Month(), beginTime.Day(), 0, 0, 0, 0, now.Location())
			endTime = now

		} else if queryType == "yesterday" {
			beginTime = now.AddDate(0, 0, -1)
			beginTime = time.Date(beginTime.Year(), beginTime.Month(), beginTime.Day(), 0, 0, 0, 0, now.Location())
			endTime = time.Date(now.Year(), now.Month(), now.Day(), 0, 0, 0, 0, now.Location())
		} else if queryType == "last_7day" {
			beginTime = now.AddDate(0, 0, -6)
			beginTime = time.Date(beginTime.Year(), beginTime.Month(), beginTime.Day(), 0, 0, 0, 0, now.Location())
			endTime = now
		} else if queryType == "last_30day" {
			beginTime = now.AddDate(0, 0, -29)
			beginTime = time.Date(beginTime.Year(), beginTime.Month(), beginTime.Day(), 0, 0, 0, 0, now.Location())
			endTime = now
		} else if queryType == "current_month" {
			endTime = now
			beginTime = time.Date(endTime.Year(), endTime.Month(), 1, 0, 0, 0, 0, now.Location())

		} else if queryType == "current_year" {
			endTime = now
			beginTime = time.Date(endTime.Year(), 1, 1, 0, 0, 0, 0, now.Location())
		} else if queryType == "last_month" {
			lastMonthTime := now.AddDate(0, -1, 0)
			beginTime = time.Date(lastMonthTime.Year(), lastMonthTime.Month(), 1, 0, 0, 0, 0, now.Location())
			endTime = time.Date(now.Year(), now.Month(), 1, 0, 0, 0, 0, now.Location())
		}

	} else {
		if beginTimeStr == "" || endTimeStr == "" {
			//如果查询类型和开始时间结束时间都未设置，按queryType=all处理
			recordCloudbrainDuration, err := models.GetDurationRecordBeginTime()
			if err != nil {
				log.Error("Can not get recordCloudbrain", err)
				ctx.Error(http.StatusBadRequest, ctx.Tr("repo.record_begintime_get_err"))
				return beginTime, endTime
			}
			if len(recordCloudbrainDuration) > 0 && err == nil {
				brainRecordBeginTime = recordCloudbrainDuration[0].DateTimeUnix.AsTime()
			} else {
				brainRecordBeginTime = now
			}
			beginTime = brainRecordBeginTime
			endTime = now
		} else {
			beginTime, err = time.ParseInLocation("2006-01-02", beginTimeStr, time.Local)
			if err != nil {
				log.Error("Can not ParseInLocation.", err)
				ctx.Error(http.StatusBadRequest, ctx.Tr("ParseInLocation_get_error"))
				return beginTime, endTime
			}
			endTime, err = time.ParseInLocation("2006-01-02", endTimeStr, time.Local)
			if err != nil {
				log.Error("Can not ParseInLocation.", err)
				ctx.Error(http.StatusBadRequest, ctx.Tr("ParseInLocation_get_error"))
				return beginTime, endTime
			}
			if endTime.After(time.Now()) {
				endTime = time.Now()
			}
		}

	}
	return beginTime, endTime
}

func getAiCenterUsageDuration(beginTime time.Time, endTime time.Time, cloudbrainStatistics []*models.CloudbrainDurationStatistic) (int, int, float64) {
	totalDuration := int(0)
	usageDuration := int(0)
	usageRate := float64(0)

	for _, cloudbrainStatistic := range cloudbrainStatistics {
		if int64(cloudbrainStatistic.DateTimeUnix) >= beginTime.Unix() && int64(cloudbrainStatistic.DateTimeUnix) < endTime.Unix() {
			totalDuration += cloudbrainStatistic.CardsTotalDuration
			usageDuration += cloudbrainStatistic.CardsUseDuration
		}
	}
	if totalDuration == 0 || usageDuration == 0 {
		usageRate = 0
	} else {
		usageRate = float64(usageDuration) / float64(totalDuration)
	}

	return totalDuration, usageDuration, usageRate
}

func getDurationStatistic(beginTime time.Time, endTime time.Time) (models.DurationRateStatistic, models.DurationRateStatistic, float64) {
	OpenITotalDuration := make(map[string]int)
	OpenIUsageDuration := make(map[string]int)
	OpenIUsageRate := make(map[string]float64)

	C2NetTotalDuration := make(map[string]int)
	C2NetUsageDuration := make(map[string]int)
	OpenIDurationRate := models.DurationRateStatistic{}
	C2NetDurationRate := models.DurationRateStatistic{}
	cardDurationStatistics, err := models.GetCardDurationStatistics(&models.DurationStatisticOptions{
		BeginTime: beginTime,
		EndTime:   endTime,
	})
	if err != nil {
		log.Error("GetCardDurationStatistics error:", err)
		return OpenIDurationRate, C2NetDurationRate, 0
	}
	for _, cloudbrainStatistic := range cardDurationStatistics {
		aiCenterName := cloudbrainStatistic.AiCenterCode + "/" + repo.GetAiCenterNameByCode(cloudbrainStatistic.AiCenterCode, "zh-CN")
		if cloudbrainStatistic.Cluster == models.OpenICluster {
			if _, ok := OpenITotalDuration[aiCenterName]; !ok {
				OpenITotalDuration[aiCenterName] = cloudbrainStatistic.CardsTotalDuration
			} else {
				OpenITotalDuration[aiCenterName] += cloudbrainStatistic.CardsTotalDuration
			}
			if _, ok := OpenIUsageDuration[aiCenterName]; !ok {
				OpenIUsageDuration[aiCenterName] = cloudbrainStatistic.CardsUseDuration
			} else {
				OpenIUsageDuration[aiCenterName] += cloudbrainStatistic.CardsUseDuration
			}
		}
		if cloudbrainStatistic.Cluster == models.C2NetCluster {
			if _, ok := C2NetTotalDuration[aiCenterName]; !ok {
				C2NetTotalDuration[aiCenterName] = cloudbrainStatistic.CardsTotalDuration
			} else {
				C2NetTotalDuration[aiCenterName] += cloudbrainStatistic.CardsTotalDuration
			}
			if _, ok := C2NetUsageDuration[aiCenterName]; !ok {
				C2NetUsageDuration[aiCenterName] = cloudbrainStatistic.CardsUseDuration
			} else {
				C2NetUsageDuration[aiCenterName] += cloudbrainStatistic.CardsUseDuration
			}
		}
	}
	ResourceAiCenterRes, err := models.GetResourceAiCenters()
	if err != nil {
		log.Error("Can not get ResourceAiCenterRes.", err)
		return OpenIDurationRate, C2NetDurationRate, 0
	}
	for _, v := range ResourceAiCenterRes {
		aiCenterName := v.AiCenterCode + "/" + repo.GetAiCenterNameByCode(v.AiCenterCode, "zh-CN")
		if cutString(v.AiCenterCode, 4) == cutString(models.AICenterOfCloudBrainOne, 4) {
			if _, ok := OpenIUsageDuration[aiCenterName]; !ok {
				OpenIUsageDuration[aiCenterName] = 0
			}
			if _, ok := OpenITotalDuration[aiCenterName]; !ok {
				OpenITotalDuration[aiCenterName] = 0
			}
		} else {
			if _, ok := C2NetUsageDuration[aiCenterName]; !ok {
				C2NetUsageDuration[aiCenterName] = 0
			}
		}
	}
	totalCanUse := float64(0)
	totalUse := float64(0)
	totalUsageRate := float64(0)
	for k, v := range OpenITotalDuration {
		for i, j := range OpenIUsageDuration {
			if k == i {
				OpenIUsageRate[k] = float64(j) / float64(v)
			}
		}
	}
	for _, v := range OpenITotalDuration {
		totalCanUse += float64(v)
	}
	for _, v := range OpenIUsageDuration {
		totalUse += float64(v)
	}
	if totalCanUse == 0 || totalUse == 0 {
		totalUsageRate = 0
	} else {
		totalUsageRate = totalUse / totalCanUse
	}
	delete(C2NetUsageDuration, "/")

	OpenIDurationRate.AiCenterTotalDurationStat = OpenITotalDuration
	OpenIDurationRate.AiCenterUsageDurationStat = OpenIUsageDuration
	OpenIDurationRate.UsageRate = OpenIUsageRate
	C2NetDurationRate.AiCenterTotalDurationStat = C2NetTotalDuration
	C2NetDurationRate.AiCenterUsageDurationStat = C2NetUsageDuration
	return OpenIDurationRate, C2NetDurationRate, totalUsageRate
}

func cutString(str string, lens int) string {
	if len(str) < lens {
		return str
	}
	return str[:lens]
}

func getDayCloudbrainDuration(beginTime time.Time, endTime time.Time, aiCenterCode string) ([]models.DateUsageStatistic, int, error) {
	now := time.Now()
	endTimeTemp := time.Date(endTime.Year(), endTime.Month(), endTime.Day(), 0, 0, 0, 0, now.Location())
	if endTimeTemp.Equal(endTime) {
		endTimeTemp = endTimeTemp.AddDate(0, 0, -1)
	}
	cardDurationStatistics, err := models.GetCardDurationStatistics(&models.DurationStatisticOptions{
		BeginTime:    beginTime,
		EndTime:      endTime,
		AiCenterCode: aiCenterCode,
	})
	if err != nil {
		log.Error("GetCardDurationStatistics error:", err)
		return nil, 0, err
	}

	dayCloudbrainInfo := make([]models.DateUsageStatistic, 0)
	count := 0
	for beginTime.Before(endTimeTemp) || beginTime.Equal(endTimeTemp) {
		TotalDuration, UsageDuration, UsageRate := getAiCenterUsageDuration(endTimeTemp, endTime, cardDurationStatistics)
		dayCloudbrainInfo = append(dayCloudbrainInfo, models.DateUsageStatistic{
			Date:          endTimeTemp.Format("2006/01/02"),
			UsageDuration: UsageDuration,
			TotalDuration: TotalDuration,
			UsageRate:     UsageRate,
		})
		endTime = endTimeTemp
		endTimeTemp = endTimeTemp.AddDate(0, 0, -1)
		if endTimeTemp.Before(beginTime) && beginTime.Before(endTime) {
			endTimeTemp = beginTime
		}
		count += 1
	}
	return dayCloudbrainInfo, count, nil
}

func getHourCloudbrainDuration(beginTime time.Time, endTime time.Time, aiCenterCode string) (models.HourTimeStatistic, error) {
	hourTimeTotalDuration := make(map[string]int)
	hourTimeUsageDuration := make(map[string]int)
	hourTimeUsageRate := make(map[string]float64)
	hourTimeStatistic := models.HourTimeStatistic{}

	cardDurationStatistics, err := models.GetCardDurationStatistics(&models.DurationStatisticOptions{
		BeginTime: beginTime,
		EndTime:   endTime,
	})
	if err != nil {
		log.Error("GetCardDurationStatistics error:", err)
		return hourTimeStatistic, err
	}
	for _, cloudbrainStatistic := range cardDurationStatistics {
		if cloudbrainStatistic.AiCenterCode == aiCenterCode {
			if _, ok := hourTimeTotalDuration[strconv.Itoa(cloudbrainStatistic.HourTime)]; !ok {
				hourTimeTotalDuration[strconv.Itoa(cloudbrainStatistic.HourTime)] = cloudbrainStatistic.CardsTotalDuration
			} else {
				hourTimeTotalDuration[strconv.Itoa(cloudbrainStatistic.HourTime)] += cloudbrainStatistic.CardsTotalDuration
			}
			if _, ok := hourTimeUsageDuration[strconv.Itoa(cloudbrainStatistic.HourTime)]; !ok {
				hourTimeUsageDuration[strconv.Itoa(cloudbrainStatistic.HourTime)] = cloudbrainStatistic.CardsUseDuration
			} else {
				hourTimeUsageDuration[strconv.Itoa(cloudbrainStatistic.HourTime)] += cloudbrainStatistic.CardsUseDuration
			}
		}
	}
	hourTimeList := []string{"0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14", "15", "16", "17", "18", "19", "20", "21", "22", "23"}
	for _, v := range hourTimeList {
		if _, ok := hourTimeUsageDuration[v]; !ok {
			hourTimeUsageDuration[v] = 0
		}
		if _, ok := hourTimeTotalDuration[v]; !ok {
			hourTimeTotalDuration[v] = 0
		}
	}

	for k, v := range hourTimeTotalDuration {
		for i, j := range hourTimeUsageDuration {
			if k == i {
				if v == 0 || j == 0 {
					hourTimeUsageRate[k] = 0
				} else {
					hourTimeUsageRate[k] = float64(j) / float64(v)
				}
			}
		}
	}

	hourTimeStatistic.HourTimeTotalDuration = hourTimeTotalDuration
	hourTimeStatistic.HourTimeUsageDuration = hourTimeUsageDuration
	hourTimeStatistic.HourTimeUsageRate = hourTimeUsageRate
	return hourTimeStatistic, nil
}

func CloudbrainUpdateAiCenter(ctx *context.Context) {
	repo.CloudbrainDurationStatisticHour()
	ctx.JSON(http.StatusOK, map[string]interface{}{
		"message": 0,
	})
}

func GetResourceQueues(ctx *context.Context) {
	resourceQueues, err := models.GetCanUseCardInfo()
	if err != nil {
		log.Error("GetCanUseCardInfo err: %v", err)
		return
	}
	Resource := make([]*models.ResourceQueue, 0)
	aiCenterCodeMap := make(map[string]string)
	for _, resourceQueue := range resourceQueues {
		if _, ok := aiCenterCodeMap[resourceQueue.AiCenterCode]; !ok {
			resourceQueue.AiCenterName = repo.GetAiCenterNameByCode(resourceQueue.AiCenterCode, ctx.Language())
			aiCenterCodeMap[resourceQueue.AiCenterCode] = resourceQueue.AiCenterCode
			Resource = append(Resource, resourceQueue)
		}
	}
	ctx.JSON(http.StatusOK, map[string]interface{}{
		"resourceQueues": Resource,
	})
}
