package load

import (
	"bufio"
	"bytes"
	"encoding/json"
	"io"
	"strings"

	"github.com/pingcap/log"
	"go.uber.org/zap"
)

const (
	maxLineSize = 1073741824
)

func Parse(reader io.Reader) TimeRangeRecords {
	records := make(TimeRangeRecords)

	scanner := bufio.NewScanner(reader)
	scanner.Buffer(nil, maxLineSize)
	for scanner.Scan() {
		line := scanner.Bytes()

		if len(line) == 0 {
			continue
		}
		if line[0] == '2' {
			if idx := bytes.IndexByte(line, '{'); idx >= 0 {
				line = line[idx:]
			}
		}

		var record *StmtRecord = &StmtRecord{}
		if err := json.Unmarshal(line, record); err != nil {
			if bytes.Contains(line, []byte("has been replaced; following end of new file")) {
				continue
			}
			log.Warn("parse statement record failed", zap.String("record", string(line)), zap.Error(err))
			continue
		}

		setSchemas(record)

		records.AddRecord(record)
	}

	if err := scanner.Err(); err != nil {
		log.Warn("scan statement records failed", zap.Error(err))
	}
	return records
}

func setSchemas(record *StmtRecord) {
	schemas := make(map[string]struct{})
	tables := strings.Split(record.TableNames, ",")
	for _, table := range tables {
		schema := strings.Trim(strings.Split(table, ".")[0], " ")
		if len(schema) > 0 {
			schemas[schema] = struct{}{}
		}
	}

	record.RelatedSchemas = schemas
}
