// todos_init is a tool to initialize the store with an initial database. This
// is really for demo purposes; in a real database, the contents would be
// persistant.
//
// The data is loaded from a JSON file, todos_init/data.json.
//
// Since JSON doesn't support all of the store types, there is a translation
// phase, where the contents are loaded into a string form, then converted to
// the todos/schema schema.
package main

import (
	"encoding/json"
	"flag"
	"fmt"
	"os"
	"os/user"
	"path/filepath"
	"strings"

	"veyron/examples/todos/schema"
	"veyron2"
	"veyron2/rt"
	"veyron2/security"
	"veyron2/storage"
	"veyron2/storage/vstore"
	"veyron2/storage/vstore/primitives"
	"veyron2/vlog"
)

var (
	storeName string
	dataPath  = flag.String("data-path", "data.json", "Path to data JSON file")
)

func init() {
	username := "unknown"
	if u, err := user.Current(); err == nil {
		username = u.Username
	}
	hostname := "unknown"
	if h, err := os.Hostname(); err == nil {
		hostname = h
	}
	// TODO(sadovsky): Change this to be the correct veyron2 path.
	dir := "global/vstore/" + hostname + "/" + username
	flag.StringVar(&storeName, "store", dir, "Name of the Veyron store")
}

// List is the JSON representation for schema.List.
// Note, we use this representation for parity with the Meteor example.
// https://www.meteor.com/examples/todos
type List struct {
	Name string
	// Each element corresponds to a schema.Item; each item is represented as a
	// list where the first element is the item name and the remaining elements
	// are tags.
	Contents [][]string
}

// state is the initial store state.
type state struct {
	store       storage.Store
	transaction storage.Transaction
}

// newState returns a fresh state.
func newState(st storage.Store) *state {
	return &state{store: st}
}

// put adds a value to the store, creating the path to the value if it doesn't
// already exist.
func (st *state) put(path string, v interface{}) {
	vlog.Infof("Storing %q = %+v", path, v)
	st.makeParentDirs(path)
	if _, err := st.store.Bind(path).Put(rt.R().TODOContext(), st.transaction, v); err != nil {
		vlog.Errorf("put failed: %s: %s", path, err)
		return
	}
}

// makeParentDirs creates the directories in a path if they do not already
// exist.
func (st *state) makeParentDirs(path string) {
	l := strings.Split(path, "/")
	for i, _ := range l {
		prefix := filepath.Join(l[:i]...)
		o := st.store.Bind(prefix)
		if _, err := o.Get(rt.R().TODOContext(), st.transaction); err != nil {
			if _, err := o.Put(rt.R().TODOContext(), st.transaction, &schema.Dir{}); err != nil {
				vlog.Errorf("Error creating parent %q: %s", prefix, err)
			}
		}
	}
}

// newTransaction starts a new transaction.
func (st *state) newTransaction() {
	st.transaction = primitives.NewTransaction(rt.R().TODOContext())
}

// commit commits the current transaction.
func (st *state) commit() {
	if err := st.transaction.Commit(rt.R().TODOContext()); err != nil {
		vlog.Errorf("Failed to commit transaction: %s", err)
	}
	st.transaction = nil
}

// storeList saves a schema.List to the store with name /lists/<Name>, and also
// saves the list's child items.
func (st *state) storeList(l *List) {
	x := &schema.List{
		Name: l.Name,
	}
	path := "/lists/" + x.Name
	st.put(path, x)

	// Store this list's child items.
	// TODO(sadovsky): Ensure that order is preserved, and is reflected in the UI.
	for i, v := range l.Contents {
		st.storeItem(path, i, v[0], v[1:])
	}
}

// storeItem saves a schema.Item to the store with name /<listPath>/Items/<id>.
// Note that <id> is defined by storeList to be the position of the item in its
// parent list.
func (st *state) storeItem(listPath string, id int, text string, tags []string) {
	x := &schema.Item{
		Text: text,
		Done: false,
		Tags: tags,
	}
	path := fmt.Sprintf("%s/Items/%d", listPath, id)
	st.put(path, x)
}

// processJSONFile saves the contents of the JSON file to the store.
func (st *state) processJSONFile(path string) error {
	vlog.Infof("Loading file %s", path)
	file, err := os.Open(path)
	if err != nil {
		return fmt.Errorf("Can't open %q: %s", path, err)
	}
	defer file.Close()

	lists := make([]*List, 0)
	decoder := json.NewDecoder(file)
	if err := decoder.Decode(&lists); err != nil {
		return fmt.Errorf("Can't decode: %s", err)
	}

	st.newTransaction()
	for _, v := range lists {
		st.storeList(v)
	}
	st.commit()
	return nil
}

// main reads the data JSON file and populates the store.
func main() {
	// The client's identity needs to match the Admin ACLs at the empty store
	// (since only the admin can put data). The identity here matches with that
	// used for server.ServerConfig.Admin in todos_stored/main.go. An alternative
	// would be to relax the ACLs on the store.
	rt.Init(veyron2.LocalID(security.FakePrivateID("anonymous")))

	vlog.Infof("Binding to store on %s", storeName)
	st, err := vstore.New(storeName)
	if err != nil {
		vlog.Fatalf("Can't connect to store: %s: %s", storeName, err)
	}
	state := newState(st)

	if err := state.processJSONFile(*dataPath); err != nil {
		vlog.Errorf("Failed to write data: %s", err)
	}
}
