package services

import (
	"fmt"
	"github.com/gogf/gf/net/ghttp"
	"github.com/gogf/gf/util/guid"
	"sparrow/pkg/models"
	"sparrow/pkg/rpcs"
	"sparrow/pkg/server"
	"sparrow/services/knowoapi/model"
)

// OtaService Ota manager
type OtaService interface {
	Create(*models.Ota) error
	Delete(*models.Ota) error
	Update(*models.Ota) error
	Query(int, int, string, string, string) ([]models.Ota, int, error)
	Get(string, string) (models.Ota, error)
	Upgrade(params models.OtaUpgradeParams) error
}

type otaService struct {
	models *model.All
}

// NewOtaService new Ota manager
func NewOtaService(models *model.All) OtaService {
	return otaService{
		models: models,
	}
}

func (a otaService) Query(pi, ps int, name, vendorId, version string) ([]models.Ota, int, error) {
	return a.models.Ota.Query(pi, ps, name, vendorId, version)
}

func (a otaService) Get(vendorId, recordId string) (models.Ota, error) {
	return a.models.Ota.Get(vendorId, recordId)
}

func (a otaService) Create(Ota *models.Ota) error {
	Ota.RecordId = guid.S()
	return a.models.Ota.Create(Ota)
}

func (a otaService) Delete(Ota *models.Ota) error {
	return a.models.Ota.Delete(Ota)
}

func (a otaService) Update(Ota *models.Ota) error {
	_, err := a.models.Ota.Update(Ota)
	return err
}

func (a otaService) Upgrade(params models.OtaUpgradeParams) error {
	ota, err := a.Get(params.VendorId, params.FileId)
	if err != nil {
		return err
	}

	devices, err := a.models.Device.Query(params.VendorId, params.ProductId, params.DeviceIDs)
	if err != nil {
		return err
	}

	client := ghttp.NewClient()
	file := client.GetVar(fmt.Sprintf("%s%s", "https://app.yongxulvjian.com", ota.Url))

	var fileArgs rpcs.ArgsOtaFile
	fileArgs.FileData = file.Bytes()
	fileArgs.FileId = int(ota.ID)
	var reply rpcs.ReplyEmptyResult

	go func() {
		for _, device := range devices {
			err = server.RPCCallByName(nil, rpcs.DeviceManagerName, "DeviceManager.SavaFile", fileArgs, &reply)
			if err != nil {
				server.Log.Errorf("OTA升级文件保存失败：%v", err)
			}
			var commandArgs rpcs.ArgsSendCommand
			commandArgs.Cmd = string(models.OtaUpgrade)
			commandArgs.DeviceId = device.DeviceIdentifier
			commandArgs.Params = map[string]interface{}{
				"fileId":   ota.ID,
				"fileSize": ota.Size,
			}

			var commandReply rpcs.ReplySendCommand
			err = server.RPCCallByName(nil, rpcs.ControllerName, "Controller.SendCommand", commandArgs, &commandReply)
			if err != nil {
				server.Log.Errorf("OTA升级指令下发失败：%v", err)
			}
		}
	}()
	return nil
}
