// Copyright 2015 The Vanadium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package util

import (
	"fmt"
	"strconv"
	"strings"

	"v.io/v23/syncbase/util"
	"v.io/v23/verror"
	"v.io/x/lib/vlog"
)

// JoinKeyParts builds keys for accessing data in the storage engine.
func JoinKeyParts(parts ...string) string {
	return strings.Join(parts, KeyPartSep)
}

// SplitKeyParts is the inverse of JoinKeyParts. Clients are generally
// encouraged to use SplitNKeyParts.
func SplitKeyParts(key string) []string {
	return strings.Split(key, KeyPartSep)
}

// SplitNKeyParts is to SplitKeyParts as strings.SplitN is to strings.Split.
func SplitNKeyParts(key string, n int) []string {
	return strings.SplitN(key, KeyPartSep, n)
}

// StripFirstKeyPartOrDie strips off the first part of the given key. Typically
// used to strip off the key prefixes defined in constants.go. Panics if the
// input string has fewer than two parts.
func StripFirstKeyPartOrDie(key string) string {
	parts := SplitNKeyParts(key, 2)
	if len(parts) < 2 {
		vlog.Fatalf("StripFirstKeyPartOrDie: invalid key %q", key)
	}
	return parts[1]
}

// FirstKeyPart returns the first part of 'key', typically a key prefix defined
// in constants.go.
func FirstKeyPart(key string) string {
	return SplitNKeyParts(key, 2)[0]
}

// IsRowKey returns true iff 'key' is a storage engine key for a row.
func IsRowKey(key string) bool {
	return FirstKeyPart(key) == RowPrefix
}

// IsPermsKey returns true iff 'key' is a storage engine key for perms.
func IsPermsKey(key string) bool {
	return FirstKeyPart(key) == PermsPrefix
}

// ParseTableAndRow extracts table and row parts from the given storage engine
// key for a row or perms. Returns an error if the given key is not a storage
// engine key for a row or perms.
func ParseTableAndRow(key string) (table string, row string, err error) {
	parts := SplitNKeyParts(key, 3)
	pfx := parts[0]
	if len(parts) < 3 || (pfx != RowPrefix && pfx != PermsPrefix) {
		return "", "", fmt.Errorf("ParseTableAndRow: invalid key %q", key)
	}
	return parts[1], parts[2], nil
}

// ParseTableAndRowOrDie calls ParseTableAndRow and panics on error.
func ParseTableAndRowOrDie(key string) (table string, row string) {
	table, row, err := ParseTableAndRow(key)
	if err != nil {
		vlog.Fatal(err)
	}
	return table, row
}

// ScanPrefixArgs returns args for sn.Scan() for the specified prefix.
func ScanPrefixArgs(stKeyPrefix, prefix string) ([]byte, []byte) {
	return ScanRangeArgs(stKeyPrefix, util.PrefixRangeStart(prefix), util.PrefixRangeLimit(prefix))
}

// ScanRangeArgs returns args for sn.Scan() for the specified range.
// If limit is "", all rows with keys >= start are included.
func ScanRangeArgs(stKeyPrefix, start, limit string) ([]byte, []byte) {
	fullStart, fullLimit := JoinKeyParts(stKeyPrefix, start), JoinKeyParts(stKeyPrefix, limit)
	if limit == "" {
		fullLimit = util.PrefixRangeLimit(fullLimit)
	}
	return []byte(fullStart), []byte(fullLimit)
}

type BatchType int

const (
	BatchTypeSn BatchType = iota // snapshot
	BatchTypeTx                  // transaction
)

// JoinBatchInfo encodes batch type and id into a single "info" string.
func JoinBatchInfo(batchType BatchType, batchId uint64) string {
	return strings.Join([]string{strconv.Itoa(int(batchType)), strconv.FormatUint(batchId, 10)}, BatchSep)
}

// SplitBatchInfo is the inverse of JoinBatchInfo.
func SplitBatchInfo(batchInfo string) (BatchType, uint64, error) {
	parts := strings.Split(batchInfo, BatchSep)
	if len(parts) != 2 {
		return BatchTypeSn, 0, verror.New(verror.ErrBadArg, nil, batchInfo)
	}
	batchTypeInt, err := strconv.Atoi(parts[0])
	if err != nil {
		return BatchTypeSn, 0, err
	}
	batchType := BatchType(batchTypeInt)
	if batchType != BatchTypeSn && batchType != BatchTypeTx {
		return BatchTypeSn, 0, verror.New(verror.ErrBadArg, nil, batchInfo)
	}
	batchId, err := strconv.ParseUint(parts[1], 0, 64)
	if err != nil {
		return BatchTypeSn, 0, err
	}
	return batchType, batchId, nil
}
