package matcher

import (
	"context"
	"strings"

	"github.com/pingcap/log"
	"github.com/tidbcloud/dataflow-service/idl/pbgen/proto/agent"
	importcfg "github.com/tidbcloud/dataflow-service/pkg/import-config"
	storagepkg "github.com/tidbcloud/dataflow-service/pkg/storage"
	"go.uber.org/zap"
)

type CustomMatcher struct {
	client     storagepkg.StorageClient
	bucket     string
	uriPrefix  string
	sourceUri  string
	dataFormat uint32
}

func NewCustomMatcher(client storagepkg.StorageClient, bucket, uriPrefix, sourceUri string, dataFormat uint32) *CustomMatcher {
	return &CustomMatcher{
		client:     client,
		bucket:     bucket,
		uriPrefix:  uriPrefix,
		sourceUri:  sourceUri,
		dataFormat: dataFormat,
	}
}

func (m *CustomMatcher) Match(ctx context.Context, targetSource *agent.SearchImportFilesReq_TargetSource) (string, error) {
	customPrefix := parseCustomRule(m.sourceUri, targetSource.CustomFile)

	objectUris, err := m.client.ListObjects(ctx, m.bucket, m.uriPrefix+customPrefix)
	if err != nil {
		return "", err
	}
	for _, uri := range objectUris {
		match, err := importcfg.MatchCustomNamingRule(uri, targetSource.CustomFile, m.dataFormat)
		if err != nil {
			return "", err
		}

		if match {
			log.L().Info("matched object", zap.String("key", uri), zap.Any("table", targetSource.TargetTable))
			return uri, nil
		}

		log.L().Info("mismatched object", zap.String("key", uri), zap.Any("table", targetSource.TargetTable))
	}

	return "", nil
}

func parseCustomRule(uriPrefix, rule string) string {
	s := strings.Split(rule, "*")
	s = strings.Split(s[0], "?")
	return strings.TrimPrefix(s[0], uriPrefix)
}
