// Copyright 2016 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 main

import (
	"fmt"
	"strconv"

	"v.io/x/lib/cmdline"
)

// TODO(youngseokyoon): add a helper command that wraps "madb exec shell pm list users" to show all available users.
var cmdMadbUser = &cmdline.Command{
	Children:         []*cmdline.Command{cmdMadbUserSet, cmdMadbUserUnset, cmdMadbUserList, cmdMadbUserClearAll},
	Name:             "user",
	DontInheritFlags: true,
	Short:            "Manage default user settings for each device",
	Long: `
Manages default user settings for each device.

An Android device can have multiple user accounts, and each user account has a numeric ID associated
with it. Certain adb commands accept '--user <user_id>' as a parameter to allow specifying which of
the Android user account should be used when running the command. The default behavior when the
user ID is not provided varies by the adb command being run.

Some madb commands internally run these adb commands which accept the '--user' flag. You can let
madb use different user IDs for different devices by storing the default user ID for each device
using 'madb user set' command. If the default user ID is not set for a particular device, madb will
not provide the '--user' flag to the underlying adb command, and the current user will be used for
that device as a result.

Below is the list of madb commands which are affected by the default user ID settings:

    madb clear-data
    madb install
    madb start
    madb stop
    madb uninstall

For more details on how to obtain the user ID from an Android device, see 'madb user help set'.
`,
}

var cmdMadbUserSet = &cmdline.Command{
	Runner: subCommandRunnerWithFilepath{runMadbUserSet, getDefaultConfigFilePath},
	Name:   "set",
	Short:  "Set a default user ID to be used for the given device.",
	Long: `
Sets a default user ID to be used for the specified device, when there are multiple user accounts on
a single device.

The user IDs can be obtained using the 'adb [<device_serial>] shell pm list users' command.
Alternatively, you can use 'madb exec' if you want to specify the device with a nickname.
For example, running the following command:

    madb -n=MyPhone exec shell pm list users

will list the available users and their IDs on the MyPhone device.
Consider the following example output:

    [MyPhone]       Users:
    [MyPhone]               UserInfo{0:John Doe:13} running
    [MyPhone]               UserInfo{10:Work profile:30} running

There are two available users, "John Doe" and "Work profile". Each user is assigned a "user ID",
which appears on the left of the user name. In this case, the user ID of "John Doe" is "0", and the
user ID of the "Work profile" is "10".

To use the "Work profile" as the default user when running madb commands on this device, run the
following command:

    madb user set MyPhone 10

and then madb will use "Work profile" as the default user for device "MyPhone" in any of the
subsequence madb commands.
`,
	ArgsName: "<device_serial> <user_id>",
	ArgsLong: `
<device_serial> is the unique serial number for the device, which can be obtained from 'adb devices'.
<user_id> is one of the user IDs obtained from 'adb shell pm list users' command.
`,
}

func runMadbUserSet(env *cmdline.Env, args []string, filename string) error {
	// Check if the arguments are valid.
	if len(args) != 2 {
		return fmt.Errorf("There must be exactly two arguments.")
	}

	// TODO(youngseokyoon): make it possible to specify the device using its nickname or index.
	// Validate the device serial
	serial := args[0]
	if !isValidSerial(serial) {
		return fmt.Errorf("Not a valid device serial: %v", serial)
	}

	// Validate the user ID.
	userID := args[1]
	if id, err := strconv.Atoi(userID); err != nil || id < 0 {
		return fmt.Errorf("Not a valid user ID: %v", userID)
	}

	cfg, err := readConfig(filename)
	if err != nil {
		return err
	}

	// Add the <device_serial, user_id> mapping for the specified device.
	cfg.UserIDs[serial] = userID
	return writeConfig(cfg, filename)
}

var cmdMadbUserUnset = &cmdline.Command{
	Runner: subCommandRunnerWithFilepath{runMadbUserUnset, getDefaultConfigFilePath},
	Name:   "unset",
	Short:  "Unset the default user ID set by the 'madb user set' command.",
	Long: `
Unsets the default user ID assigned by the 'madb user set' command for the specified device.

Running this command without any device specifiers will unset the default users only for the
currently available devices and emulators, while keeping the default user IDs for the other devices.
`,
	ArgsName: "<device_serial>",
	ArgsLong: `
<device_serial> is the unique serial number for the device, which can be obtained from 'adb devices'.
`,
}

func runMadbUserUnset(env *cmdline.Env, args []string, filename string) error {
	// Check if the arguments are valid.
	if len(args) != 1 {
		return fmt.Errorf("There must be exactly one argument.")
	}

	// TODO(youngseokyoon): make it possible to specify the device using its nickname or index.
	// Validate the device serial
	serial := args[0]
	if !isValidSerial(serial) {
		return fmt.Errorf("Not a valid device serial: %v", serial)
	}

	cfg, err := readConfig(filename)
	if err != nil {
		return err
	}

	delete(cfg.UserIDs, serial)
	return writeConfig(cfg, filename)
}

var cmdMadbUserList = &cmdline.Command{
	Runner: subCommandRunnerWithFilepath{runMadbUserList, getDefaultConfigFilePath},
	Name:   "list",
	Short:  "List all the existing default user IDs.",
	Long: `
Lists all the currently stored default user IDs for devices.
`,
}

func runMadbUserList(env *cmdline.Env, args []string, filename string) error {
	cfg, err := readConfig(filename)
	if err != nil {
		return err
	}

	// TODO(youngseokyoon): pretty print this.
	fmt.Println("Device Serial    User ID")
	fmt.Println("========================")

	for s, u := range cfg.UserIDs {
		fmt.Printf("%v\t%v\n", s, u)
	}

	return nil
}

var cmdMadbUserClearAll = &cmdline.Command{
	Runner: subCommandRunnerWithFilepath{runMadbUserClearAll, getDefaultConfigFilePath},
	Name:   "clear-all",
	Short:  "Clear all the existing default user settings.",
	Long: `
Clears all the currently stored default user IDs for devices.

This command clears the default user IDs regardless of whether the device is currently connected or not.
`,
}

func runMadbUserClearAll(env *cmdline.Env, args []string, filename string) error {
	cfg, err := readConfig(filename)
	if err != nil {
		return err
	}

	cfg.UserIDs = make(map[string]string)
	return writeConfig(cfg, filename)
}
