// Package service add by blacknc <blacknc@163.com> at 2023/01/16 16:38:05
package service

import (
	"context"
	entity "dataapps/internal/entity/sqleditor"
	repository "dataapps/internal/repository/sqleditor"
	"errors"
	"strings"
	"time"

	"github.com/tidbcloud/tiinf/errs"
	"github.com/tidbcloud/tiinf/monitor/tilog"
	"go.uber.org/zap"
	"gorm.io/gorm/logger"
)

func CreateOplog(ctx context.Context, param entity.SqlEditorOplog) error {

	// filte aitestsuite
	if param.CreatedBy == "internal" {
		return nil
	}
	if param.EventType != string(entity.EventTypeGenSql) && param.Chat2QuerySId != "" {
		var (
			gensqlLog *entity.SqlEditorOplog
			err       error
		)
		for i := 0; i < 3; i++ {
			gensqlLog, err = ShowOplog(ctx, param.Chat2QuerySId, string(entity.EventTypeGenSql))
			if err != nil {
				return errs.NewInternalDB("Statements query gen_sql log failed", err)
			} else if gensqlLog != nil {
				break
			}
			time.Sleep(time.Second)
		}
		if gensqlLog == nil {
			return errs.NewBadRequest("Statements query gen_sql log not found", err)
		}
		param.IsModified = !isContainSpl(gensqlLog.SqlContent, param.SqlContent)
		param.UserQuestion = gensqlLog.UserQuestion
		param.PromptVersion = gensqlLog.PromptVersion
		param.Channel = gensqlLog.Channel
		if param.EventType == string(entity.EventTypeSqlAccept) {
			param.Status = 1
			param.Databases = gensqlLog.Databases
		}
		if param.EventType == string(entity.EventTypeExecSql) {
			param.IsAccept = true
		}
	}
	param.CreatedAt = time.Now()
	err := repository.CreateOplog(param)
	if err != nil {
		return err
	}
	return nil
}

func ShowOplog(ctx context.Context, chat2querySid string, eventType string) (*entity.SqlEditorOplog, error) {
	res, err := repository.ShowOplog(chat2querySid, eventType)
	if err != nil {
		if errors.Is(err, logger.ErrRecordNotFound) {
			return nil, nil
		}
		tilog.Error(ctx, "ShowOplog failed.", zap.Error(err))
		return nil, err
	}
	return res, nil
}

func isContainSpl(s1, s2 string) bool {
	s1 = strings.TrimSpace(s1)
	s2 = strings.TrimSpace(s2)
	s1 = strings.ReplaceAll(s1, " \n", "")
	s2 = strings.ReplaceAll(s2, " \n", "")
	s1 = strings.ReplaceAll(s1, "\n", "")
	s2 = strings.ReplaceAll(s2, "\n", "")
	return strings.Contains(s1, s2)
}
