// 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 sbtree

import (
	"fmt"

	"v.io/v23/context"
	wire "v.io/v23/services/syncbase"
	"v.io/v23/syncbase"
)

// CollectionTree has all the data for the collection page of the Syncbase debug
// viewer.
type CollectionTree struct {
	Service    syncbase.Service
	Database   syncbase.Database
	Collection syncbase.Collection
	RowCount   int
	TotKeySize uint64
	KeysPage   keysPage
}

type keyVal struct {
	Index int
	Key   string
	Value interface{}
}

// keysPage is a contiguous subset of the keys, used for pagination.
type keysPage struct {
	HasPrev bool
	KeyVals []keyVal
	NextKey string
}

// AssembleCollectionTree returns information describing the given Syncbase
// collection, including a "page" of keys starting at the given first key.
func AssembleCollectionTree(
	ctx *context.T, server, dbBlessing, dbName, collBlessing, collName, firstKey string, keysPerPage int,
) *CollectionTree {
	var (
		dbId    = wire.Id{dbBlessing, dbName}
		collId  = wire.Id{collBlessing, collName}
		service = syncbase.NewService(server)

		// TODO(eobrain) Confirm nil for schema is appropriate
		db   = service.DatabaseForId(dbId, nil)
		coll = db.CollectionForId(collId)
	)

	rowCount, totKeySize, page := scanCollection(ctx, coll, firstKey, keysPerPage)
	return &CollectionTree{service, db, coll, rowCount, totKeySize, page}
}

// scanCollection gets some statistics, plus a page of key-value pairs starting
// with firstKey.
func scanCollection(
	ctx *context.T, coll syncbase.Collection, firstKey string, keysPerPage int,
) (rowCount int, totKeySize uint64, page keysPage) {
	page.KeyVals = make([]keyVal, 0, keysPerPage)

	stream := coll.Scan(ctx, syncbase.Prefix(""))

	// We scan through all the keys lexicographically, and when we come to a
	// key >= firstKey we start gathering a "page" of keys. As we scan, a
	// state machine keeps track of whether we are before the page, in the
	// page, or after the page.
	const (
		before    = 0
		gathering = iota
		done      = iota
	)
	state := before
	for stream.Advance() {
		key := stream.Key()
		totKeySize += uint64(len(key))

		switch state {
		case before:
			if key >= firstKey {
				// First key found: transition to gathering the page
				state = gathering
			} else {
				// There is at least one key before the page
				page.HasPrev = true
			}
		case gathering:
			if len(page.KeyVals) >= keysPerPage {
				// Page full: transition to done.  There is at
				// least one key after the page.
				state = done
				page.NextKey = key
			}
		case done:
			// Done gathering.  Terminal state.
		}
		if state == gathering {
			// Grab the value, put it and the key into a KeyVal, and
			// add it to the page.
			var value interface{}
			err := stream.Value(&value)
			if err != nil {
				value = fmt.Sprintf("ERROR getting value: %v", err)
			}
			page.KeyVals = append(page.KeyVals, keyVal{rowCount, key, value})
		}
		rowCount++
	}
	return
}
