#!/usr/bin/env python2


# user facing commands:
#
#  -- write_statjson_hostnames
#  -- do_quick_add



# pretty_dump_board:

# Given the name of a board, dump it to a directory with
# the following structure:

# data.dir
#   - hostname1
#   - hostname2
#   - hostname3

# NEXT, report all the ways in which hostnames of that board are not valid
# jsonified protobufs for adding a new DUT.
#
# this involves shelling out to skylab validate-new-dut-json



# adding a dut that's already present
# $ skylab quick-add-dut /tmp/json
# Deployment ID:         d604b46b-87c7-4a4d-8b8a-ed97565c4797
# Status:                DUT_DEPLOYMENT_STATUS_FAILED
# Inventory change URL:
# Deploy task URL:
# Message:               failed to add DUT(s) to fleet: add dut to fleet: inventory store commit: nothing to commit


# adding a dut successfully
# $ skylab quick-add-dut /tmp/json
# Deployment ID:         8e27b3ff-39ad-4b92-9bea-3f804a9d7bf9
# Status:                DUT_DEPLOYMENT_STATUS_FAILED
# Inventory change URL:  https://chrome-internal-review.googlesource.com/c/chromeos/infra_internal/skylab_inventory/+/1940714
# Deploy task URL:
# Message:               missing deploy task ID in deploy request entry



# $ atest host rename --for-migration --non-interactive chromeos2-row1-rack7-host1
# Successfully renamed:
# chromeos2-row1-rack7-host1 to chromeos2-row1-rack7-host1-migrated-do-not-use


# unsuccessful lock

# $ atest host mod --lock -r 'migration to skylab' chromeos2-row1-rack7-host1-migrated-do-not-use
# Operation modify_host failed:
#     ValidationError: {'locked': u'Host chromeos2-row1-rack7-host1-migrated-do-not-use already locked by pprabhu on 2019-08-29 16:48:51.'}
#    1


# successful lock



from __future__ import print_function
from __future__ import unicode_literals
import os
import sys
import subprocess
import pipes
import os.path
import warnings
import json
import tempfile
import shutil

TEXT = (type(b""), type(u""))
NONETYPE = type(None)


def flush_sync(fh):
    fh.flush()
    os.fsync(fh)
    return


# accepts: shell command, rest of args
# returns: exit_status, stdout, stderr
def shell_capture_all(cmd, *rest):
    shellcmd = ("bash", "-c", cmd, "bash",) + rest
    pr = subprocess.Popen(
        shellcmd,
        stdout=subprocess.PIPE,
        stderr=subprocess.PIPE,
    )
    stdout, stderr = pr.communicate()
    return pr.returncode, stdout, stderr


# accepts: name of board
# returns: list of hostnames, error message (None if no error)
def get_all_hosts_for_board(board):
    # extract just the hostnames for all the hosts in the board
    cmd = "set -o pipefail; ( atest host list --label=%%%LABEL%%% | awk '{print $1}' )"
    cmd = cmd.replace("%%%LABEL%%%", pipes.quote("board:%s" % board))
    returncode, out, err = shell_capture_all(cmd)
    if returncode != 0:
        return None, "get_all_hosts_for_board: " + err
    hostnames = [x.strip() for x in out.split()]
    if hostnames and hostnames[0] == "Host":
        hostnames.pop(0)
    return hostnames, None


# make a directory and test if we can write to it as defensively as possible
# free vars: %%%DEST%%%
MAKE_DIR_CMD = r"""
mkdir -p %%%DEST%%%
cd %%%DEST%%% && touch ./writeable && rm ./writeable
"""


# free vars: %%%HOSTNAME%%% %%%DEST%%%
STATJSON_CMD = r"""
atest host statjson %%%HOSTNAME%%% 1>%%%DEST%%%/%%%HOSTNAME%%%
"""

# accepts: path to directory
# returns: error message (None if successfully made dir)
def mkdirp(dirpath):
    cmd = MAKE_DIR_CMD.replace('%%%DEST%%%', pipes.quote(dirpath))
    returncode, out, err = shell_capture_all(cmd)
    if returncode == 0:
        return None
    else:
        return err


# accepts: list of hostnames, output directory (path)
# returns: successful hosts, failed hosts, error message (None if no error)
def write_statjson_hostnames(hostnames, outdir):
    successful_hosts = []
    failed_hosts = []
    err = mkdirp(outdir)
    if err is not None:
        return None, None, err
    for hostname in hostnames:
        cmd = STATJSON_CMD
        cmd = cmd.replace('%%%HOSTNAME%%%', pipes.quote(hostname))
        cmd = cmd.replace('%%%DEST%%%', pipes.quote(outdir))
        returncode, out, err = shell_capture_all(cmd)
        if returncode == 0:
            successful_hosts.append(hostname)
        else:
            failed_hosts.append(hostname)
    return successful_hosts, failed_hosts, None


# accepts: board name, output directory
# returns: successful hosts, failed hosts, error message
def write_statjson_board(board, outdir):
    hostnames, err = get_all_hosts_for_board(board)
    if err is not None:
        return None, None, err
    successful_hosts, failed_hosts, err = write_statjson_hostnames(hostnames, outdir)
    return successful_hosts, failed_hosts, err


# free vars: %%%PATH%%%
VALIDATE_CMD = r"""
skylab validate-new-dut-json %%%PATH%%%
"""


# accepts: directory with hostname files
# returns: dictionary of the form below, error message (or None if no error)
#
# {
#    hostname: error message (or None if no error)
# }
def validate_output(hostname_dir):
    try:
        paths = os.listdir(hostname_dir)
    except OSError:
        return None, ("bad directory: %s" % hostname_dir)

    # defensively populate result dictionary with errors
    # so that we don't erroneously conclude that an unvisited
    # hostname was validated
    result = {}
    for path in paths:
        result[path] = "DID NOT PROCESS"

    for path in paths:
        cmd = VALIDATE_CMD
        cmd = cmd.replace('%%%PATH%%%', pipes.quote(os.path.join(hostname_dir, path)))
        returncode, out, err = shell_capture_all(cmd)
        if returncode != 0:
            result[path] = "failed to validate (errcode %s): %s" % (returncode, err)
        elif os.path.exists(os.path.join(hostname_dir, path)):
            result[path] = None
        else:
            warnings.warn("nonexistent path %s" % path)
            result[path] = "file does not exist"

    return result, None



# accepts: name of board, output directory
# returns: dictionary of form below, error message (or None if no error)
#
# {
#    hostname: error-message or NOFILE if no file or None if no error
# }
def process_board(board, output_dir):
    queried_hosts, unqueried_hosts, err = write_statjson_board(board, output_dir)
    if err is not None:
        return None, err
    validate_result, err = validate_output(output_dir)
    if err is not None:
        return None, err
    result = {}

    for hostname in queried_hosts:
        try:
            result[hostname] = validate_result[hostname]
        except KeyError:
            warnings.warn("hostname (%s) not present in validate_result")

    for hostname in unqueried_hosts:
        result["hostname"] = "NOFILE"

    return result, None


# accepts: name of board, output directory
# returns: number of bad hosts
# emits:   prints error message for every bad host
def pretty_process_board(board, output_dir):
    result, err = process_board(board, output_dir)
    if err is not None:
        print(err)
        return 1
    bad_results = {}
    for k in result:
        if result[k] is not None:
            bad_results[k] = result[k]
    # no bad results --> nothing printed
    for k in bad_result:
        print(k, result[k])
    return len(bad_results)


# accepts: path to output directory
# returns: combined json object, error message (None if no error)
# NOTE: the directory not existing is a fatal error
#       processing a file that is invalid json AFTER the output directory
#       has been validated produces a warning. the invalid json situation
#       should be impossible, but also isn't enough to prevent assemble_output_dir
#       from doing something reasonable.
def assemble_output_dir(output_dir):
    _, err = validate_output(output_dir)
    if err is not None:
        return None, err
    out = []
    items = None
    try:
        items = os.listdir(output_dir)
    except OSError:
        return None, ("directory %s does not exist or is not readable" % output_dir)
    for item in items:
        obj = None
        try:
            with open(os.path.join(output_dir, item), "r") as fh:
                try:
                    obj = json.load(fh)
                except ValueError:
                    warnings.warn("file %s does not contain valid JSON" % item)
                    continue
        except IOError:
            warnings.warn("file %s somehow doesn't exist" % item)
            continue
        out.append(obj)
    return out, None


# accepts: single json dictionary
# returns: error message (None if valid)
def validate_single_dut_json(obj):
    with tempfile.NamedTemporaryFile(delete=True) as fh:
        json.dump(obj, fh)
        flush_sync(fh)
        cmd = VALIDATE_CMD
        cmd = cmd.replace('%%%PATH%%%', pipes.quote(fh.name))
        returncode, out, err = shell_capture_all(cmd)
        if returncode == 0:
            return None
        else:
            return err


# accepts: json obj
# returns: hostname, error message (None if no error)
def get_hostname_from_dut_json(obj):
    try:
        common = obj["common"]
    except KeyError:
        return None, "dut has no common element"
    if not isinstance(common, dict):
        return None, ("common block must be dict not %s" % type(common))
    try:
        return common["hostname"], None
    except KeyError:
        return None, "common block has no hostname element"


# accepts: path to file
# returns: hostname mapping, error message
# hostname mapping has the following form
#
# {
#    hostname -> new_dut_info_json
# }
#
# malformed entries are not included in the map
def load_hostname_map_file(filepath):
    obj = None
    try:
        with open(filepath, "r") as fh:
            try:
                obj = json.load(fh)
            except ValueError:
                return None, ("file does not contain JSON %s" % filepath)
    except IOError:
        return None, ("cannot load hostname map from nonexistent file %s" % filepath)

    out = {}

    # return a singleton map if the toplevel entry is a dictionary
    if isinstance(obj, dict):
        err = validate_single_dut_json(obj)
        if err is not None:
            return None, err
        hostname, err = get_hostname_from_dut_json(obj)
        if err is not None:
            return None, err
        return {hostname: obj}, None

    # validate all elements if the toplevel entry is a list
    elif isinstance(obj, list):
        for subobj in obj:
            err = validate_single_dut_json(subobj)
            if err is not None:
                warnings.warn(err)
                continue
            hostname, err = get_hostname_from_dut_json(subobj)
            if err is not None:
                warnings.warn(err)
                continue
            # warn if we get a duplicate, but don't halt execution
            if hostname in out:
                warnings.warn(("duplicate hostname %s" % hostname))
            out[hostname] = subobj

    if len(out) == 0:
        return out, "out cannot be empty"

    return out, None


# accepts: path to directory
# returns: hostnaming mapping, error message
# hostname mapping has the following form
#
# {
#    hostname -> new_dut_info_json
# }
#
# malformed entries are not included in the map
def load_hostname_map(dirpath):
    items = None
    try:
        items = os.listdir(dirpath)
    except OSError:
        return None, ("cannot load from nonexistent directory %s" % dirpath)
    if len(items) == 0:
        return None, ("nothing in directory %s" % dirpath)
    out = {}
    for item in items:
        hostname_map, err = load_hostname_map_file(os.path.join(dirpath, item))
        if err is not None:
            warnings.warn(err)
            continue

        for hostname in hostname_map:
            if hostname in out:
                warnings.warn("load_hostname_map: duplicate hostname %s" % hostname)
                continue
            out[hostname] = hostname_map[hostname]

    return out, None


# free vars: %%%DIR%%%
QUICK_ADD_DUTS_CMD = r"""
skylab quick-add-duts %%%DIR%%%/*
"""


# accepts: list of hostnames, hostname_dirpath
# returns: error message (None if successful)
# NOTE: the quick-add-duts API is atomic
# emits: missing hostnames when there are missing hostnames
def do_quick_add_duts(hostnames, dirpath):
    # validation
    if isinstance(hostnames, TEXT):
        return "hostnames cannot be %s" % type(hostnames)
    # defensively prevent hostnames from being modified
    hostnames = tuple(hostnames)
    for hostname in hostnames:
        if hostname.startswith("."):
            return "hostname cannot start with '.' (%s)" % hostname
        if not hostname:
            return "hostname cannot be falsey (%s)" % hostname


    hostnames_map, err = load_hostname_map(dirpath)
    if err is not None:
        return err

    # check that every hostname is in the map before trying
    missing_hostnames = set([])
    for hostname in hostnames:
        if hostname not in hostnames_map:
            missing_hostnames.add(hostname)

    if missing_hostnames:
        for hostname in sorted(missing_hostnames):
            print(("MISSING %s" % hostname))
        return "%s missing hostnames" % len(missing_hostnames)

    try:
        # construct temporary directory of dut files.
        tdir = tempfile.mkdtemp()
        for hostname in hostnames:
            newpath = os.path.join(tdir, hostname)
            with open(newpath, "w") as fh:
                json.dump(obj=hostnames_map[hostname], fp=fh)

        # paranoia, check number of files.
        num_files = len(os.listdir(tdir))
        if num_files != len(hostnames):
            return "internal error. hostnames: %s, files: %s, tdir: %s" % (len(hostnames), num_files, tdir)

        # validate directory contents before proceeding
        _, err = validate_output(tdir)
        if err is not None:
            return err

        # execute the command, transfer file contents to skylab
        # NOTE: this step is atomic
        # note... skylab quick-add-duts will claim there's no deploy task ID
        # when it is successful
        # we need to parse the output to tell what happened
        #
        # right now, I use the presence of the magic strings 'nothing to commit'
        # and 'missing deploy task ID in request entry' to diagnose what happened
        # but this is fragile.
        cmd = QUICK_ADD_DUTS_CMD
        cmd = cmd.replace('%%%DIR%%%', pipes.quote(tdir))
        returncode, out, err = shell_capture_all(cmd)
        if " nothing to commit" in out:
            warnings.warn("nothing to commit ... no change made to inventory")
            return None
        elif "missing deploy task ID in deploy request entry" in out:
            print("SUCCESS!")
            print(out)
            return None
        else:
            return ("%s\n%s" % (out, err))
    finally:
        print(("path to tempdir: %s" % tdir))


# free vars: %%%MLIST%%%
ATEST_LOCK_RENAME_CMD = r"""

tdir="$(mktemp -d)"
test -d "$tdir" || exit 10

# produce the unmangled hostnames
cat -- %%%MLIST%%% | sed -e 's/-migrated-do-not-use$//' > "$tdir"/unmangled
cat -- "$tdir"/unmangled | sed -e 's/$/-migrated-do-not-use//' > "$tdir"/mangled

# just attempt to lock, discard results
# first process unmangled names
atest host mod --lock -r 'migration to skylab' --mlist "$tdir"/unmangled 2>&1
# then process mangled names
atest host mod --lock -r 'migration to skylab' --mlist "$tdir"/mangled   2>&1

# next attempt to rename only the unmangled names
atest host rename --for-migration --non-interactive --mlist "$tdir"/unmangled 2>&1

"""


# accepts: hostnames
# returns: error message (None if no error)
# emits:   output
def atest_lock_rename(hostnames):
    if isinstance(hostnames, TEXT):
        return "hostnames cannot be text"
    
    with tempfile.NamedTemporaryFile(delete=True) as fh:
        for hostname in hostnames:
            fh.write(hostname.strip())
            fh.write("\n")
        flush_sync(fh)
        cmd = ATEST_LOCK_RENAME_CMD
        cmd = cmd.replace('%%%MLIST%%%', pipes.quote(fh.name))
        returncode, out, err = shell_capture_all(cmd)

        print(out)        
        return None
