package log_merger

import (
	"context"

	logpattern_go_proto "github.com/pingcap-inc/alioth/proto"
	"github.com/pingcap-inc/alioth/recorder"
	"github.com/pingcap-inc/alioth/storage"
)

type mergeStore struct {
	store *storage.LogPatternStore

	path        string
	coverage    *recorder.Coverage
	unknownLogs *recorder.UnknowLogRecord
	pattern     *recorder.LogPattern
}

func newMergeStore(storePath string) (*mergeStore, error) {
	store, err := storage.NewStore(storePath)
	if err != nil {
		return nil, err
	}

	return &mergeStore{
		store:       store,
		path:        storePath,
		coverage:    recorder.NewCoverager(store),
		unknownLogs: recorder.NewUnknowLogRecorder(store),
		pattern:     recorder.NewLogPattern(store),
	}, nil
}

func (m *mergeStore) Foreach(ctx context.Context, mergedItem *mergeStore) error {
	err := m.coverage.LoadCoverage(ctx)
	if err != nil {
		return err
	}

	err = m.coverage.Forach(ctx, mergedItem.MergeCoverage)
	if err != nil {
		return err
	}

	err = m.unknownLogs.LoadUnknowLogs(ctx)
	if err != nil {
		return err
	}
	err = m.unknownLogs.Forach(ctx, mergedItem.MergeUnknownLogs)
	if err != nil {
		return err
	}

	err = m.pattern.LoadPattern(ctx)
	if err != nil {
		return err
	}
	return m.pattern.Forach(ctx, mergedItem.MergePattern)
}

func (m *mergeStore) MergeCoverage(ctx context.Context, record *logpattern_go_proto.Coverage) error {
	return m.coverage.Merge(ctx, record)
}

func (m *mergeStore) MergeUnknownLogs(ctx context.Context, record *logpattern_go_proto.UnknowLogPattern) error {
	return m.unknownLogs.Merge(ctx, record)
}

func (m *mergeStore) MergePattern(ctx context.Context, lp *logpattern_go_proto.LogPattern) error {
	m.pattern.Record(lp)
	return nil
}

func (m *mergeStore) Close(ctx context.Context) error {
	return m.store.Close(ctx)
}

func (m *mergeStore) Flush(ctx context.Context) error {
	if err := m.coverage.Flush(ctx); err != nil {
		return err
	}

	if err := m.pattern.Flush(ctx); err != nil {
		return err
	}

	return m.unknownLogs.Flush(ctx)
}
