#!python
""" gpu-ls  -  Displays details about installed and compatible GPUs

    Part of the rickslab-gpu-utils package which includes gpu-ls, gpu-mon, gpu-pac, and
    gpu-plot.

    This utility displays most relevant parameters for installed and compatible GPUs. The
    default behavior is to list relevant parameters by GPU.  OpenCL platform information is
    added when the *--clinfo* option is used.  A brief listing of key parameters is available
    with the *--short* command line option.  A simplified table of current GPU state is
    displayed with the *--table* option. The *--no_fan* can be used to ignore fan settings.  The
    *--pstate* option can be used to output the p-state table for each GPU instead of the list
    of basic parameters.  The *--ppm* option is used to output the table of available
    power/performance modes instead of basic parameters.  The *--force_all* results in an attempt
    to read all possible sensors, regardless of how the GPU is classified.  The *--raw* will
    read all possible driver files and display with indicators of if a gpu-util key word and
    description is associated with each file along with its contents.  The *--verbose* option
    will display progress and informational messages generated by the utilities.  By default,
    output data is formatted and color coded, so the *--no_markup* option can be specified
    to get plain text.

    Copyright (C) 2019  RicksLab

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <https://www.gnu.org/licenses/>.
"""
__author__ = 'RueiKe'
__copyright__ = 'Copyright (C) 2019 RicksLab'
__credits__ = ['Craig Echt - Testing, Debug, Verification, and Documentation',
               'Keith Myers - Testing, Debug, Verification of NV Capability']
__license__ = 'GNU General Public License'
__program_name__ = 'gpu-ls'
__maintainer__ = 'RueiKe'
__docformat__ = 'reStructuredText'
# pylint: disable=multiple-statements
# pylint: disable=line-too-long
# pylint: disable=bad-continuation

import argparse
import sys
import logging
from GPUmodules import __version__, __status__
from GPUmodules import GPUmodule as Gpu
from GPUmodules import env

LOGGER = logging.getLogger('gpu-utils')


def main() -> None:
    """
    Main flow for gpu-ls.
    """
    parser = argparse.ArgumentParser()
    parser.add_argument('--about', help='README',
                        action='store_true', default=False)
    parser.add_argument('--short', help='Short listing of basic GPU details',
                        action='store_true', default=False)
    parser.add_argument('--table', help='Current status of readable GPUs',
                        action='store_true', default=False)
    parser.add_argument('--pstates', help='Output pstate tables instead of GPU details',
                        action='store_true', default=False)
    parser.add_argument('--ppm', help='Output power/performance mode tables instead of GPU details',
                        action='store_true', default=False)
    parser.add_argument('--clinfo', help='Include openCL with card details',
                        action='store_true', default=False)
    parser.add_argument('--verbose', help='Display informational message of GPU util progress',
                        action='store_true', default=False)
    parser.add_argument('--force_all', help='Force attempt to read all sensors',
                        action='store_true', default=False)
    parser.add_argument('--raw', help='Show all raw GPU sensor data',
                        action='store_true', default=False)
    parser.add_argument('--no_markup', help='Do not format ls output',
                        action='store_true', default=False)
    parser.add_argument('--no_fan', help='Do not include fan setting options',
                        action='store_true', default=False)
    parser.add_argument('-d', '--debug', help='Debug logger output',
                        action='store_true', default=False)
    args = parser.parse_args()

    # About me
    if args.about:
        print(__doc__)
        print('Author: ', __author__)
        print('Copyright: ', __copyright__)
        print('Credits: ', *['\n      {}'.format(item) for item in __credits__])
        print('License: ', __license__)
        print('Version: ', __version__)
        print('Install Type: ', env.GUT_CONST.install_type)
        print('Maintainer: ', __maintainer__)
        print('Status: ', __status__)
        sys.exit(0)

    if args.short: args.no_fan = True
    env.GUT_CONST.set_args(args)
    LOGGER.debug('########## %s %s', __program_name__, __version__)

    if env.GUT_CONST.check_env() < 0:
        print('Error in environment. Exiting...')
        sys.exit(-1)

    if (args.pstates or args.ppm) and (args.table or args.raw):
        print('The --table/--raw options can not be used with --pstate or --ppm, ignoring --table/--raw')
        args.table = args.raw = False

    # Get list of GPUs and exit if no GPUs detected
    gpu_list = Gpu.GpuList()
    gpu_list.set_gpu_list(clinfo_flag=True)
    num_gpus = gpu_list.num_gpus()
    if num_gpus['total'] == 0:
        print('No GPUs detected, exiting...')
        sys.exit(-1)

    # Display vendor and driver details
    Gpu.print_driver_vendor_summary(gpu_list)

    # Read data static/dynamic/info/state driver information for GPUs
    gpu_list.read_gpu_sensor_set(data_type=Gpu.GpuItem.SensorSet.All)

    # Check number of readable/writable GPUs again
    Gpu.print_gpu_rw_summary(gpu_list)

    # If specified, display raw sensor details
    if args.raw:
        gpu_list.read_raw_sensors()
        gpu_list.print_raw()
        sys.exit(0)

    # Read report clinfo specific details
    if args.clinfo:
        if not gpu_list.read_gpu_opencl_data():
            args.clinfo = False

    # Print out user requested details
    gpu_list.read_gpu_pstates()
    if args.pstates:
        gpu_list.print_pstates()
    if args.ppm:
        gpu_list.read_gpu_ppm_table()
        gpu_list.print_ppm_table()
    if not args.pstates and not args.ppm:
        if args.table:
            com_gpu_list = Gpu.set_mon_plot_compatible_gpu_list(gpu_list)
            com_gpu_list.print_table(title='Status of Compatible GPUs:')
        else:
            gpu_list.print(short=args.short, clflag=args.clinfo)

    sys.exit(0)


if __name__ == '__main__':
    main()
