// Binary bank is a bank client that interacts with bankd and pbankd.
// Users connect to a bank service and can send commands to it.
package main

import (
	"bufio"
	"flag"
	"fmt"
	"os"
	"strconv"
	"strings"

	"veyron/examples/bank"
	vsecurity "veyron/security"
	idutil "veyron/services/identity/util"

	"veyron2"
	"veyron2/naming"
	"veyron2/rt"
	"veyron2/security"
)

var (
	// TODO(rthellend): Remove the address flag when the config manager is working.
	address               = flag.String("address", "", "the address/endpoint of the bank server")
	serverPattern         = flag.String("server_pattern", "*", "server_pattern is an optional pattern for the expected identity of the fortune server. Example: the pattern \"myorg/fortune\" matches identities with names \"myorg/fortune\" or \"myorg\". If the flag is absent then the default pattern \"*\" matches all identities.")
	accountMountTableName string
)

const bankMountTableName string = "veyron/bank"

// Parses str and returns a nonnegative integer
func getInt(str string, name string) (int64, bool) {
	v, err := strconv.ParseInt(str, 0, 64)
	if err != nil {
		fmt.Printf("given %s %s was not an integer: %s\n", name, str, err)
		return 0, true
	}
	return v, false
}

func main() {
	// Create the Veyron runtime using VEYRON_IDENTITY
	runtime := rt.Init()
	log := runtime.Logger()

	// Construct a new stub that binds to serverEndpoint without
	// using the name service
	var bankServer bank.Bank
	var err error
	if *address != "" {
		bankServer, err = bank.BindBank(naming.JoinAddressName(*address, "//bank"))
	} else {
		bankServer, err = bank.BindBank("veyron/bank")
	}
	if err != nil {
		log.Fatal("error binding to server: ", err)
	}

	// First, Connect to the bank to retrieve the location you should bind to.
	newIdentity, bankAccountNumber, err := bankServer.Connect(runtime.TODOContext(), veyron2.RemoteID(*serverPattern))
	if err != nil {
		log.Fatalf("%s.Connect failed: %s\n", bankMountTableName, err)
	}
	fmt.Printf("Successfully connected to the bank with account: %d\n", bankAccountNumber)

	client := runtime.Client()
	// If you got a new identity, you should update your PrivateID and make a new client with that identity.
	if newIdentity != "" {
		// Decode the new identity
		var newPublicID security.PublicID
		err := idutil.Base64VomDecode(newIdentity, &newPublicID)
		if err != nil {
			log.Fatalf("failed to decode the given public id: %s\n", err)
		}

		// Derive the new PrivateID
		derivedIdentity, err := runtime.Identity().Derive(newPublicID)
		if err != nil {
			log.Fatalf("failed to derive identity: %s\n", err)
		}

		// Update the PrivateID at VEYRON_IDENTITY
		path := os.Getenv("VEYRON_IDENTITY")
		f, err := os.OpenFile(path, os.O_WRONLY, 0600)
		if err != nil {
			log.Fatalf("failed to open identity file for writing: %s\n", err)
		}
		err = vsecurity.SaveIdentity(f, derivedIdentity)
		if err != nil {
			log.Fatalf("failed to save identity: %s\n", err)
		}
		err = f.Close()
		if err != nil {
			log.Fatalf("could not close file %q, %s\n", path, err)
		}

		// Make a NewClient and update the other one. Do not close the old client; we need its connection to the Mount Table.
		client, err = runtime.NewClient(veyron2.LocalID(newPublicID))
		if err != nil {
			log.Fatalf("failed to create new client: %s\n", err)
		}
	}

	// Bind to the bank account service
	accountMountTableName = fmt.Sprintf("veyron/bank/%d", bankAccountNumber)
	bindLocation := fmt.Sprintf("//bank/%d", bankAccountNumber)
	var accountServer bank.BankAccount
	if *address != "" { // Connect directly to the server's endpoint
		accountServer, err = bank.BindBankAccount(naming.JoinAddressName(*address, bindLocation), client)
	} else { // Use the Mount Table to connect to the server
		accountServer, err = bank.BindBankAccount(accountMountTableName, client)
	}
	if err != nil {
		log.Fatalf("error binding to server: ", err)
	}

	// Read commands from standard input until the user decides to quit/exit.
	end := false
	for !end {
		fmt.Print("Your command: ")

		// Read input from user
		in := bufio.NewReader(os.Stdin)
		input, _ := in.ReadString('\n')
		commands := strings.Fields(input)

		if len(commands) == 0 {
			fmt.Println("Please enter a command. 'help' displays the list of commands.")
			continue
		}

		switch commands[0] {
		case "bankAccountNumber":
			fmt.Printf("Your bank account number is %d\n", bankAccountNumber)
		case "deposit":
			if len(commands) < 2 {
				fmt.Println("deposit takes an amount")
				break
			}
			amount, e := getInt(commands[1], "amount")
			if e {
				break
			}
			err := accountServer.Deposit(runtime.TODOContext(), amount, veyron2.RemoteID(*serverPattern))
			if err != nil {
				fmt.Printf("%s.Deposit failed: %s\n", accountMountTableName, err)
				break
			}
			fmt.Printf("Deposited %d\n", amount)
		case "withdraw":
			if len(commands) < 2 {
				fmt.Println("withdraw takes an amount")
				break
			}
			amount, e := getInt(commands[1], "amount")
			if e {
				break
			}
			err := accountServer.Withdraw(runtime.TODOContext(), amount, veyron2.RemoteID(*serverPattern))
			if err != nil {
				fmt.Printf("%s.Withdraw failed: %s\n", accountMountTableName, err)
				break
			}
			fmt.Printf("Withdrew %d\n", amount)
		case "transfer":
			if len(commands) < 3 {
				fmt.Println("transfer takes an account number and an amount")
				break
			}
			accountNumber, e1 := getInt(commands[1], "account number")
			amount, e2 := getInt(commands[2], "amount")
			if e1 || e2 {
				break
			}
			err := accountServer.Transfer(runtime.TODOContext(), accountNumber, amount, veyron2.RemoteID(*serverPattern))
			if err != nil {
				fmt.Printf("%s.Transfer failed: %s\n", accountMountTableName, err)
				break
			}
			fmt.Printf("Transferred %d to %d\n", amount, accountNumber)
		case "balance":
			balance, err := accountServer.Balance(runtime.TODOContext(), veyron2.RemoteID(*serverPattern))
			if err != nil {
				fmt.Printf("%s.Balance failed: %s\n", accountMountTableName, err)
				break
			}
			fmt.Printf("User has balance %d\n", balance)
		case "help":
			fmt.Println("You can do the following actions:")
			fmt.Println("bankAccountNumber: check your account number")
			fmt.Println("balance: check your account balance")
			fmt.Println("deposit [N>=0]: deposit money into your account")
			fmt.Println("withdraw [N>=0]: withdraw money from your account")
			fmt.Println("transfer [account number] [N>=0]: transfer money to another account")
			fmt.Println("quit: quit the program")
			fmt.Println("exit: also quits the program")
		case "exit", "quit":
			fmt.Println("Quitting...")
			end = true
		default:
			fmt.Printf("Unknown command: %s\n", commands[0])
		}
	}
}
