package core

import (
	"ZhenTuLocalPassiveAdapter/config"
	"ZhenTuLocalPassiveAdapter/dto"
	"ZhenTuLocalPassiveAdapter/fs"
	"ZhenTuLocalPassiveAdapter/util"
	"context"
	"fmt"
	"go.opentelemetry.io/otel"
	"go.opentelemetry.io/otel/attribute"
	"go.opentelemetry.io/otel/codes"
	"log"
	"os"
	"path"
)

var tracer = otel.Tracer("task")

func HandleTask(ctx context.Context, device config.DeviceMapping, task dto.Task) (*dto.FileObject, error) {
	subCtx, span := tracer.Start(ctx, "HandleTask")
	defer span.End()
	adapter := fs.GetAdapter()
	span.SetAttributes(attribute.String("task.id", task.TaskID))
	span.SetAttributes(attribute.String("task", util.ToJson(task)))
	span.SetAttributes(attribute.String("device.no", device.DeviceNo))
	span.SetAttributes(attribute.String("device.name", device.Name))
	fileList, err := adapter.GetFileList(
		subCtx,
		path.Join(device.Name, task.StartTime.Format("2006"+config.Config.FileName.DateSeparator+"01"+config.Config.FileName.DateSeparator+"02")),
		task.StartTime,
	)
	if err != nil {
		span.SetAttributes(attribute.String("error", err.Error()))
		span.SetStatus(codes.Error, "获取文件列表失败")
		log.Printf("获取文件列表失败, DeviceNo: %s, 错误: %v\n", device.DeviceNo, err)
		return nil, err
	}
	files := util.FilterAndSortFiles(subCtx, fileList, task.StartTime, task.EndTime)
	if len(files) == 0 {
		span.SetStatus(codes.Error, "没有找到文件")
		return nil, fmt.Errorf("没有找到文件")
	}
	span.SetAttributes(attribute.Int("fileCount", len(files)))
	constructTask, err := util.CheckFileCoverageAndConstructTask(subCtx, files, task.StartTime, task.EndTime, task)
	if err != nil {
		span.SetAttributes(attribute.String("error", err.Error()))
		span.SetStatus(codes.Error, "文件片段检查失败")
		log.Printf("文件片段检查失败, DeviceNo: %s, 错误: %v\n", device.DeviceNo, err)
		return nil, err
	}
	ok := util.RunFfmpegTask(subCtx, constructTask)
	if !ok {
		span.SetAttributes(attribute.String("error", "ffmpeg任务执行失败"))
		span.SetStatus(codes.Error, "ffmpeg任务执行失败")
		return nil, fmt.Errorf("ffmpeg任务执行失败")
	}
	outfile, err := os.Stat(constructTask.OutputFile)
	if err != nil {
		span.SetAttributes(attribute.String("error", err.Error()))
		span.SetStatus(codes.Error, "文件不存在")
		return nil, fmt.Errorf("文件不存在:%s", constructTask.OutputFile)
	}
	span.SetAttributes(attribute.String("file.name", outfile.Name()))
	span.SetAttributes(attribute.Int64("file.size", outfile.Size()))
	if outfile.Size() < 4096 {
		span.SetAttributes(attribute.String("error", "文件大小过小"))
		span.SetStatus(codes.Error, "文件大小过小")
		return nil, fmt.Errorf("文件大小过小:%s", constructTask.OutputFile)
	}
	return &dto.FileObject{
		CreateTime:   task.EndTime,
		EndTime:      task.EndTime,
		NeedDownload: true,
		URL:          constructTask.OutputFile,
	}, nil
}