'''
Copyright 2019 Google LLC

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    https://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
'''


import os
import sys


CONFIG_BASEDIR = os.path.join(os.path.expanduser("~"), ".config", "mdt")
CONFIG_ATTRDIR = os.path.join(CONFIG_BASEDIR, "attribs")

DEFAULT_USERNAME = "mendel"
DEFAULT_PASSWORD = "mendel"
DEFAULT_DISABLE_PASSWD_AUTH = "true"


class Config:
    def __init__(self):
        self.ensureConfigDirExists()

    def ensureConfigDirExists(self):
        if not os.path.exists(CONFIG_BASEDIR):
            os.makedirs(CONFIG_BASEDIR, mode=0o700)
        if not os.path.exists(CONFIG_ATTRDIR):
            os.makedirs(CONFIG_ATTRDIR, mode=0o700)

    def getAttribute(self, name, default=None):
        path = os.path.join(CONFIG_ATTRDIR, name)
        if os.path.exists(path):
            with open(path, "r") as fp:
                return fp.readline().rstrip()

        return default

    def setAttribute(self, name, value):
        path = os.path.join(CONFIG_ATTRDIR, name)
        with open(path, "w") as fp:
            fp.write(value + "\n")

    def clearAttribute(self, name):
        path = os.path.join(CONFIG_ATTRDIR, name)
        if os.path.exists(path):
            os.unlink(path)

    def preferredDevice(self, devicename=None):
        if not devicename:
            return self.getAttribute("preferred-device")
        self.setAttribute("preferred-device", devicename)

    def username(self, username=None):
        if not username:
            return self.getAttribute("username", DEFAULT_USERNAME)
        self.setAttribute("username", username)

    def password(self, password=None):
        if not password:
            return self.getAttribute("password", DEFAULT_PASSWORD)
        self.setAttribute("password", password)

    def shouldDisablePasswordAuth(self, disablePasswdAuth=None):
        if disablePasswdAuth == None:
            return self.getAttribute("disable-password-auth",
                                     DEFAULT_DISABLE_PASSWD_AUTH)
        self.setAttribute("disable-password-auth", disablePasswdAuth)


class GetCommand:
    '''Usage: mdt get [<variablename>]

Returns the value currently set for a given variable name. Some useful
nvariables are:

    preferred-device    - set this to your preferred device name to default
                          most commands to manipulating this specific device.
                          This can be set to an IPv4 address to bypass the mDNS
                          lookup.
    username            - set this to the username that should be used to
                          connect to a device with. Defaults to 'mendel'.
    password            - set this to the password to use to login to a new
                          device with. Defaults to 'mendel'. Only used
                          during the initial setup phase of pushing an SSH
                          key to the board.

If no variable name is provided, 'mdt get' will print out the list of all
known stored variables and their values. Note: default values are not printed.
'''

    def __init__(self):
        self.config = Config()

    def run(self, args):
        if len(args) == 2:
            value = self.config.getAttribute(args[1])
            if value == None:
                print("{0} is unset".format(args[1]))
            else:
                print("{0} is {1}".format(args[1],
                                    self.config.getAttribute(args[1])))
        else:
            print("Usage: mdt get [<variablename>]")


class SetCommand:
    '''Usage: mdt set <variablename> <value>

Sets the value for a given variable name. Some useful variables are:

    preferred-device    - set this to your preferred device name to default
                          most commands to manipulating this specific device.
                          This can be set to an IPv4 address to bypass the mDNS
                          lookup.
    username            - set this to the username that should be used to
                          connect to a device with. Defaults to 'mendel'.
    password            - set this to the password to use to login to a new
                          device with. Defaults to 'mendel'. Only used
                          during the initial setup phase of pushing an SSH
                          key to the board.

Note that setting a variable to the empty string does not clear it back to
the default value! Use 'mdt clear' for that.
'''
    def __init__(self):
        self.config = Config()

    def run(self, args):
        if len(args) != 3:
            print("Usage: mdt set <variablename> <value>")
            return 1

        self.config.setAttribute(args[1], args[2])
        print("Set {0} to {1}".format(args[1], args[2]))


class ClearCommand:
    '''Usage: mdt clear <variablename>

Clears the value for a given variable name, resetting it back to its
default value.
'''
    def __init__(self):
        self.config = Config()

    def run(self, args):
        if args:
            self.config.clearAttribute(args[1])
            print("Cleared {0}".format(args[1]))
