#!/usr/bin/env python3
# SPDX-License-Identifier: GPL-2.0
#
# Program to allow users to fuzz test Hyper-V drivers
# by interfacing with Hyper-V debugfs attributes.
# Current test methods available:
#       1. delay testing
#
# Current file/directory structure of hyper-V debugfs:
#       /sys/kernel/debug/hyperv/UUID
#       /sys/kernel/debug/hyperv/UUID/<test-state filename>
#       /sys/kernel/debug/hyperv/UUID/<test-method sub-directory>
#
# author: Branden Bonaby <brandonbonaby94@gmail.com>

import os
import cmd
import argparse
import glob
from argparse import RawDescriptionHelpFormatter
from argparse import RawTextHelpFormatter
from enum import Enum

# Do not change unless, you change the debugfs attributes
# in /drivers/hv/debugfs.c. All fuzz testing
# attributes will start with "fuzz_test".

# debugfs path for hyperv must exist before proceeding
debugfs_hyperv_path = "/sys/kernel/debug/hyperv"
if not os.path.isdir(debugfs_hyperv_path):
        print("{} doesn't exist/check permissions".format(debugfs_hyperv_path))
        exit(-1)

class dev_state(Enum):
        off = 0
        on = 1

# File names, that correspond to the files created in
# /drivers/hv/debugfs.c
class f_names(Enum):
        state_f = "fuzz_test_state"
        buff_f =  "fuzz_test_buffer_interrupt_delay"
        mess_f =  "fuzz_test_message_delay"

# Both single_actions and all_actions are used
# for error checking and to allow for some subparser
# names to be abbreviated. Do not abbreviate the
# test method names, as it will become less intuitive
# as to what the user can do. If you do decide to
# abbreviate the test method name, make sure the main
# function reflects this change.

all_actions = [
        "disable_all",
        "D",
        "enable_all",
        "view_all",
        "V"
]

single_actions = [
        "disable_single",
        "d",
        "enable_single",
        "view_single",
        "v"
]

def main():

        file_map = recursive_file_lookup(debugfs_hyperv_path, dict())
        args = parse_args()
        if (not args.action):
                print ("Error, no options selected...exiting")
                exit(-1)
        arg_set = { k for (k,v) in vars(args).items() if v and k != "action" }
        arg_set.add(args.action)
        path = args.path if "path" in arg_set else None
        if (path and path[-1] == "/"):
                path = path[:-1]
        validate_args_path(path, arg_set, file_map)
        if (path and "enable_single" in arg_set):
            state_path = locate_state(path, file_map)
            set_test_state(state_path, dev_state.on.value, args.quiet)

        # Use subparsers as the key for different actions
        if ("delay" in arg_set):
                validate_delay_values(args.delay_time)
                if (args.enable_all):
                        set_delay_all_devices(file_map, args.delay_time,
                                              args.quiet)
                else:
                        set_delay_values(path, file_map, args.delay_time,
                                         args.quiet)
        elif ("disable_all" in arg_set or "D" in arg_set):
                disable_all_testing(file_map)
        elif ("disable_single" in arg_set or "d" in arg_set):
                disable_testing_single_device(path, file_map)
        elif ("view_all" in arg_set or "V" in arg_set):
                get_all_devices_test_status(file_map)
        elif ("view_single" in arg_set or  "v" in arg_set):
                get_device_test_values(path, file_map)

# Get the state location
def locate_state(device, file_map):
        return file_map[device][f_names.state_f.value]

# Validate delay values to make sure they are acceptable to
# enable delays on a device
def validate_delay_values(delay):

        if (delay[0]  == -1 and delay[1] == -1):
                print("\nError, At least 1 value must be greater than 0")
                exit(-1)
        for i in delay:
                if (i < -1 or i == 0 or i > 1000):
                        print("\nError, Values must be  equal to -1 "
                              "or be > 0 and <= 1000")
                        exit(-1)

# Validate argument path
def validate_args_path(path, arg_set, file_map):

        if (not path and any(element in arg_set for element in single_actions)):
                print("Error, path (-p) REQUIRED for the specified option. "
                      "Use (-h) to check usage.")
                exit(-1)
        elif (path and any(item in arg_set for item in all_actions)):
                print("Error, path (-p) NOT REQUIRED for the specified option. "
                      "Use (-h) to check usage." )
                exit(-1)
        elif (path not in file_map and any(item in arg_set
                                           for item in single_actions)):
                print("Error, path '{}' not a valid vmbus device".format(path))
                exit(-1)

# display Testing status of single device
def get_device_test_values(path, file_map):

        for name in file_map[path]:
                file_location = file_map[path][name]
                print( name + " = " + str(read_test_files(file_location)))

# Create a map of the vmbus devices and their associated files
# [key=device, value = [key = filename, value = file path]]
def recursive_file_lookup(path, file_map):

        for f_path in glob.iglob(path + '**/*'):
                if (os.path.isfile(f_path)):
                        if (f_path.rsplit("/",2)[0] == debugfs_hyperv_path):
                                directory = f_path.rsplit("/",1)[0]
                        else:
                                directory = f_path.rsplit("/",2)[0]
                        f_name = f_path.split("/")[-1]
                        if (file_map.get(directory)):
                                file_map[directory].update({f_name:f_path})
                        else:
                                file_map[directory] = {f_name:f_path}
                elif (os.path.isdir(f_path)):
                        recursive_file_lookup(f_path,file_map)
        return file_map

# display Testing state of devices
def get_all_devices_test_status(file_map):

        for device in file_map:
                if (get_test_state(locate_state(device, file_map)) is 1):
                        print("Testing = ON for: {}"
                              .format(device.split("/")[5]))
                else:
                        print("Testing = OFF for: {}"
                              .format(device.split("/")[5]))

# read the vmbus device files, path must be absolute path before calling
def read_test_files(path):
        try:
                with open(path,"r") as f:
                        file_value = f.readline().strip()
                return int(file_value)

        except IOError as e:
                errno, strerror = e.args
                print("I/O error({0}): {1} on file {2}"
                      .format(errno, strerror, path))
                exit(-1)
        except ValueError:
                print ("Element to int conversion error in: \n{}".format(path))
                exit(-1)

# writing to vmbus device files, path must be absolute path before calling
def write_test_files(path, value):

        try:
                with open(path,"w") as f:
                        f.write("{}".format(value))
        except IOError as e:
                errno, strerror = e.args
                print("I/O error({0}): {1} on file {2}"
                      .format(errno, strerror, path))
                exit(-1)

# set testing state of device
def set_test_state(state_path, state_value, quiet):

        write_test_files(state_path, state_value)
        if (get_test_state(state_path) is 1):
                if (not quiet):
                        print("Testing = ON for device: {}"
                              .format(state_path.split("/")[5]))
        else:
                if (not quiet):
                        print("Testing = OFF for device: {}"
                              .format(state_path.split("/")[5]))

# get testing state of device
def get_test_state(state_path):
        #state == 1 - test = ON
        #state == 0 - test = OFF
        return  read_test_files(state_path)

# write 1 - 1000 microseconds, into a single device using the
# fuzz_test_buffer_interrupt_delay and fuzz_test_message_delay
# debugfs attributes
def set_delay_values(device, file_map, delay_length, quiet):

        try:
                interrupt = file_map[device][f_names.buff_f.value]
                message = file_map[device][f_names.mess_f.value]

                # delay[0]- buffer interrupt delay, delay[1]- message delay
                if (delay_length[0] >= 0 and delay_length[0] <= 1000):
                        write_test_files(interrupt, delay_length[0])
                if (delay_length[1] >= 0 and delay_length[1] <= 1000):
                        write_test_files(message, delay_length[1])
                if (not quiet):
                        print("Buffer delay testing = {} for: {}"
                              .format(read_test_files(interrupt),
                                      interrupt.split("/")[5]))
                        print("Message delay testing = {} for: {}"
                              .format(read_test_files(message),
                                      message.split("/")[5]))
        except IOError as e:
                errno, strerror = e.args
                print("I/O error({0}): {1} on files {2}{3}"
                      .format(errno, strerror, interrupt, message))
                exit(-1)

# enabling delay testing on all devices
def set_delay_all_devices(file_map, delay, quiet):

        for device in (file_map):
                set_test_state(locate_state(device, file_map),
                               dev_state.on.value,
                               quiet)
                set_delay_values(device, file_map, delay, quiet)

# disable all testing on a SINGLE device.
def disable_testing_single_device(device, file_map):

        for name in file_map[device]:
                file_location = file_map[device][name]
                write_test_files(file_location, dev_state.off.value)
        print("ALL testing now OFF for {}".format(device.split("/")[-1]))

# disable all testing on ALL devices
def disable_all_testing(file_map):

        for device in file_map:
                disable_testing_single_device(device, file_map)

def parse_args():
        parser = argparse.ArgumentParser(prog = "vmbus_testing",usage ="\n"
                "%(prog)s [delay]   [-h] [-e|-E] -t [-p]\n"
                "%(prog)s [view_all       | V]      [-h]\n"
                "%(prog)s [disable_all    | D]      [-h]\n"
                "%(prog)s [disable_single | d]      [-h|-p]\n"
                "%(prog)s [view_single    | v]      [-h|-p]\n"
                "%(prog)s --version\n",
                description = "\nUse lsvmbus to get vmbus device type "
                "information.\n" "\nThe debugfs root path is "
                "/sys/kernel/debug/hyperv",
                formatter_class = RawDescriptionHelpFormatter)
        subparsers = parser.add_subparsers(dest = "action")
        parser.add_argument("--version", action = "version",
                version = '%(prog)s 0.1.0')
        parser.add_argument("-q","--quiet", action = "store_true",
                help = "silence none important test messages."
                       " This will only work when enabling testing"
                       " on a device.")
        # Use the path parser to hold the --path attribute so it can
        # be shared between subparsers. Also do the same for the state
        # parser, as all testing methods will use --enable_all and
        # enable_single.
        path_parser = argparse.ArgumentParser(add_help=False)
        path_parser.add_argument("-p","--path", metavar = "",
                help = "Debugfs path to a vmbus device. The path "
                "must be the absolute path to the device.")
        state_parser = argparse.ArgumentParser(add_help=False)
        state_group = state_parser.add_mutually_exclusive_group(required = True)
        state_group.add_argument("-E", "--enable_all", action = "store_const",
                                 const = "enable_all",
                                 help = "Enable the specified test type "
                                 "on ALL vmbus devices.")
        state_group.add_argument("-e", "--enable_single",
                                 action = "store_const",
                                 const = "enable_single",
                                 help = "Enable the specified test type on a "
                                 "SINGLE vmbus device.")
        parser_delay = subparsers.add_parser("delay",
                        parents = [state_parser, path_parser],
                        help = "Delay the ring buffer interrupt or the "
                        "ring buffer message reads in microseconds.",
                        prog = "vmbus_testing",
                        usage = "%(prog)s [-h]\n"
                        "%(prog)s -E -t [value] [value]\n"
                        "%(prog)s -e -t [value] [value] -p",
                        description = "Delay the ring buffer interrupt for "
                        "vmbus devices, or delay the ring buffer message "
                        "reads for vmbus devices (both in microseconds). This "
                        "is only on the host to guest channel.")
        parser_delay.add_argument("-t", "--delay_time", metavar = "", nargs = 2,
                        type = check_range, default =[0,0], required = (True),
                        help = "Set [buffer] & [message] delay time. "
                        "Value constraints: -1 == value "
                        "or 0 < value <= 1000.\n"
                        "Use -1 to keep the previous value for that delay "
                        "type, or a value > 0 <= 1000 to change the delay "
                        "time.")
        parser_dis_all = subparsers.add_parser("disable_all",
                        aliases = ['D'], prog = "vmbus_testing",
                        usage = "%(prog)s [disable_all | D] -h\n"
                        "%(prog)s [disable_all | D]\n",
                        help = "Disable ALL testing on ALL vmbus devices.",
                        description = "Disable ALL testing on ALL vmbus "
                        "devices.")
        parser_dis_single = subparsers.add_parser("disable_single",
                        aliases = ['d'],
                        parents = [path_parser], prog = "vmbus_testing",
                        usage = "%(prog)s [disable_single | d] -h\n"
                        "%(prog)s [disable_single | d] -p\n",
                        help = "Disable ALL testing on a SINGLE vmbus device.",
                        description = "Disable ALL testing on a SINGLE vmbus "
                        "device.")
        parser_view_all = subparsers.add_parser("view_all", aliases = ['V'],
                        help = "View the test state for ALL vmbus devices.",
                        prog = "vmbus_testing",
                        usage = "%(prog)s [view_all | V] -h\n"
                        "%(prog)s [view_all | V]\n",
                        description = "This shows the test state for ALL the "
                        "vmbus devices.")
        parser_view_single = subparsers.add_parser("view_single",
                        aliases = ['v'],parents = [path_parser],
                        help = "View the test values for a SINGLE vmbus "
                        "device.",
                        description = "This shows the test values for a SINGLE "
                        "vmbus device.", prog = "vmbus_testing",
                        usage = "%(prog)s [view_single | v] -h\n"
                        "%(prog)s [view_single | v] -p")

        return  parser.parse_args()

# value checking for range checking input in parser
def check_range(arg1):

        try:
                val = int(arg1)
        except ValueError as err:
                raise argparse.ArgumentTypeError(str(err))
        if val < -1 or val > 1000:
                message = ("\n\nvalue must be -1 or  0 < value <= 1000. "
                           "Value program received: {}\n").format(val)
                raise argparse.ArgumentTypeError(message)
        return val

if __name__ == "__main__":
        main()
