#! /usr/bin/env python3

"""Collect the corresponding information of nic"""

import os
import shutil
import argparse
from subprocess import Popen, PIPE

DEV_LIST = ["0x4000", "0x6000", "0x3800"]
VENDOR_LIST = ["0x19ee", "0x1da8"]
CONFIG_DEBUG_SCMD = False
SCRIPT_LOG = ""
BSP_PATHS = ["/opt/corigine/bin", "/opt/netronome/bin"]
REQ_SHELL_TOOLS = ["tar"]

# Map of island number to human readable component
# isl_nr: (name, nr_me's)
ISL_MAP = {
    1: ("ARM", 4),
    4: ("PCIe0", 4),
    5: ("PCIe1", 4),
    6: ("PCIe2", 4),
    7: ("PCIe3", 4),
    8: ("NBI0", 0),
    9: ("NBI1", 0),
    12: ("Crypto0", 8),
    13: ("Crypto1", 8),
    24: ("ExternalMUEng0", 0),
    25: ("ExternalMUEng1", 0),
    26: ("ExternalMUEng2", 0),
    28: ("InternalMUEng0", 0),
    29: ("InternalMUEng1", 0),
    32: ("MECl0", 12),
    33: ("MECl1", 12),
    34: ("MECl2", 12),
    35: ("MECl3", 12),
    36: ("MECl4", 12),
    37: ("MECl5", 12),
    38: ("MECl6", 12),
    48: ("Interlaken-LA0", 4),
    49: ("Interlaken-LA1", 4),
    }

rtsyms_to_dump = [
    "BLM_0_ISLAND_ID",
    "MAP_CMSG_Q_BASE",
    "SLICC_HASH_PAD_DATA",
    "_BLM_NBI8_BLQ0_EMU_QD_BASE",
    "_BLM_NBI8_BLQ0_EMU_Q_BASE",
    "_BLM_NBI8_BLQ1_EMU_QD_BASE",
    "_BLM_NBI8_BLQ1_EMU_Q_BASE",
    "_BLM_NBI8_BLQ2_EMU_QD_BASE",
    "_BLM_NBI8_BLQ2_EMU_Q_BASE",
    "_BLM_NBI8_BLQ3_EMU_QD_BASE",
    "_BLM_NBI8_BLQ3_EMU_Q_BASE",
    "_NIC_CFG_MCAST_INSTR_TBL",
    "__pv_pkt_sequencer",
    "_abi_cfg_lut_error_cnt",
    "_abi_dcb_cfg",
    "_abi_nfd_out_red_offload_0",
    "_abi_pcie_error_cnt",
    "_cfg_error_rss_cntr",
    "_fl_buf_sz_cache",
    "_gro_bm_0_0",
    "_gro_bm_0_1",
    "_gro_bm_0_2",
    "_gro_bm_0_3",
    "_gro_bm_1_0",
    "_gro_bm_1_1",
    "_gro_bm_1_2",
    "_gro_bm_1_3",
    "_gro_bm_2_0",
    "_gro_bm_2_1",
    "_gro_bm_2_2",
    "_gro_bm_2_3",
    "_gro_bm_3_0",
    "_gro_bm_3_1",
    "_gro_bm_3_2",
    "_gro_bm_3_3",
    "_gro_cli_cntrs",
    "_gro_global_config",
    "_gro_q_0_0",
    "_gro_q_0_1",
    "_gro_q_0_2",
    "_gro_q_0_3",
    "_gro_q_1_0",
    "_gro_q_1_1",
    "_gro_q_1_2",
    "_gro_q_1_3",
    "_gro_q_2_0",
    "_gro_q_2_1",
    "_gro_q_2_2",
    "_gro_q_2_3",
    "_gro_q_3_0",
    "_gro_q_3_1",
    "_gro_q_3_2",
    "_gro_q_3_3",
    "_mac_lkup_tbl",
    "_mac_stats",
    "_multi_pf_natqs_mask",
    "_multi_pf_of_vid",
    "_multi_pf_vf_alloc",
    "_nfd_cfg_multi_pf_state",
    "_nfd_stats_in_recv",
    "_nfd_stats_out_drop",
    "_nfd_stats_out_sent",
    "_nic_cfg_synch",
    "_nic_stats_queue",
    "_nic_stats_vnic",
    "_nic_vlan_to_vnics_map_tbl",
    "_no_mcast_filter_cache",
    "_pf0_net_app_cap",
    "_pf0_net_app_id",
    "_pf0_net_bar0",
    "_pf0_net_ctrl_bar",
    "_pf0_net_vf_cfg2",
    "_pf1_net_app_cap",
    "_pf1_net_app_id",
    "_pf1_net_bar0",
    "_pf1_net_vf_cfg2",
    "blm_pci4_blq_stash",
    "cmsg_dbg_enq__cntr__",
    "cmsg_dbg_rxq__cntr__",
    "cmsg_enq__cntr__",
    "cmsg_err__cntr__",
    "cmsg_err_no_credits__cntr__",
    "cmsg_rx__cntr__",
    "cmsg_rx_bad_type__cntr__",
    "cmsg_tx__cntr__",
    "debugdebug_journal",
    "fl_cache_mem0",
    "gro_release_ring_mem_0",
    "gro_release_ring_mem_1",
    "gro_release_ring_mem_2",
    "gro_release_ring_mem_3",
    "i12.NIC_CFG_INSTR_TBL_NBI",
    "i12.NIC_CFG_INSTR_TBL_NFD",
    "i12.NIC_RSS_TBL",
    "i12._feature_counters",
    "i32.NIC_CFG_INSTR_TBL_NBI",
    "i32.NIC_CFG_INSTR_TBL_NFD",
    "i32.NIC_RSS_TBL",
    "i32._feature_counters",
    "i33.NIC_CFG_INSTR_TBL_NBI",
    "i33.NIC_CFG_INSTR_TBL_NFD",
    "i33.NIC_RSS_TBL",
    "i33._feature_counters",
    "i34.BLM_BLQ0_CACHE_BASE",
    "i34.BLM_BLQ1_CACHE_BASE",
    "i34.BLM_BLQ2_CACHE_BASE",
    "i34.BLM_BLQ3_CACHE_BASE",
    "i34.BLM_EGRESS_NULL_BUF_RECYCLE_BASE_0",
    "i34.BLM_INFO_SECTION_BASE",
    "i34.BLM_INGRESS_NULL_BUF_RECYCLE_BASE_0",
    "i34.CTM_BLQ0_STATS_BASE",
    "i34.CTM_BLQ1_STATS_BASE",
    "i34.CTM_BLQ2_STATS_BASE",
    "i34.CTM_BLQ3_STATS_BASE",
    "i34.CTM_NBI_BLQ0_STATS_BASE",
    "i34.CTM_NBI_BLQ1_STATS_BASE",
    "i34.CTM_NBI_BLQ2_STATS_BASE",
    "i34.CTM_NBI_BLQ3_STATS_BASE",
    "i34.NIC_CFG_INSTR_TBL_NBI",
    "i34.NIC_CFG_INSTR_TBL_NFD",
    "i34.NIC_RSS_TBL",
    "i34._feature_counters",
    "i34._nvnic_macs",
    "i34.me10._multicast_addr_cntrs",
    "i34.me10._queue_stat_error_flag",
    "i34.me10._vf_cfg_rate",
    "i35.NIC_CFG_INSTR_TBL_NBI",
    "i35.NIC_CFG_INSTR_TBL_NFD",
    "i35.NIC_RSS_TBL",
    "i35._feature_counters",
    "i35._pkt_buf_ctm_credits",
    "i36.NIC_CFG_INSTR_TBL_NBI",
    "i36.NIC_CFG_INSTR_TBL_NFD",
    "i36.NIC_RSS_TBL",
    "i36._feature_counters",
    "i36._pkt_buf_ctm_credits",
    "i36.me10._msix_cls_automask",
    "i36.me10._msix_cls_rx_enabled",
    "i36.me10._msix_cls_rx_entries",
    "i36.me10._msix_cls_rx_new_enabled",
    "i36.me10._msix_cls_tx_enabled",
    "i36.me10._msix_cls_tx_entries",
    "i36.me10._msix_cls_tx_new_enabled",
    "i36.me10._msix_rx_irqc_cfg",
    "i36.me10._msix_rx_irqc_state",
    "i36.me10._msix_tx_irqc_cfg",
    "i36.me10._msix_tx_irqc_state",
    "i4._lso_hdr_data",
    "i4._nfd_in_issued_ring0",
    "i4._nfd_in_issued_ring1",
    "i4.me7._msix_cls_automask",
    "i4.me7._msix_cls_rx_enabled",
    "i4.me7._msix_cls_rx_entries",
    "i4.me7._msix_cls_rx_new_enabled",
    "i4.me7._msix_cls_tx_enabled",
    "i4.me7._msix_cls_tx_entries",
    "i4.me7._msix_cls_tx_new_enabled",
    "i4.me7._msix_cls_txr_wb_enabled",
    "i4.me7._msix_rx_irqc_cfg",
    "i4.me7._msix_rx_irqc_state",
    "i4.me7._msix_tx_irqc_cfg",
    "i4.me7._msix_tx_irqc_state",
    "i4.me7._msix_txr_wb_addr",
    "i4.nfd_active_bmsk_atomic",
    "i4.nfd_in_active_bmsk",
    "i4.nfd_in_batch_mem",
    "i4.nfd_in_gpd_wq_mem0",
    "i4.nfd_out_active_bmsk",
    "i4.nfd_out_active_bmsk_atomic",
    "i4.nfd_out_sb_wq_credits0",
    "i4.nfd_out_sb_wq_mem0",
    "i4.nfd_queue_event_mem0",
    "i48.BLM_BLQ0_CACHE_BASE",
    "i48.BLM_BLQ1_CACHE_BASE",
    "i48.BLM_BLQ2_CACHE_BASE",
    "i48.BLM_BLQ3_CACHE_BASE",
    "i48.BLM_EGRESS_NULL_BUF_RECYCLE_BASE_0",
    "i48.BLM_INFO_SECTION_BASE",
    "i48.BLM_INGRESS_NULL_BUF_RECYCLE_BASE_0",
    "i48.CTM_BLQ0_STATS_BASE",
    "i48.CTM_BLQ1_STATS_BASE",
    "i48.CTM_BLQ2_STATS_BASE",
    "i48.CTM_BLQ3_STATS_BASE",
    "i48.CTM_NBI_BLQ0_STATS_BASE",
    "i48.CTM_NBI_BLQ1_STATS_BASE",
    "i48.CTM_NBI_BLQ2_STATS_BASE",
    "i48.CTM_NBI_BLQ3_STATS_BASE",
    "i48.nfd_out_sb_wq_credits0",
    "i48.nfd_out_sb_wq_mem0",
    "mem_meter",
    "mem_meter_cfg",
    "nbi0_dma_bpe_credits",
    "nfd_cfg_bar0_base0",
    "nfd_cfg_bar1_base0",
    "nfd_cfg_base0",
    "nfd_cfg_msg_jrnl",
    "nfd_cfg_pf0_num_ports",
    "nfd_cfg_pf1_num_ports",
    "nfd_cfg_ring_mem",
    "nfd_cfg_ring_mem00",
    "nfd_cfg_ring_mem01",
    "nfd_cfg_ring_mem02",
    "nfd_cfg_ring_mem03",
    "nfd_cfg_ring_mem04",
    "nfd_cfg_ring_mem05",
    "nfd_cfg_ring_mem06",
    "nfd_cfg_state_jrnl",
    "nfd_cfg_tlv_template0",
    "nfd_flr_atomic",
    "nfd_flr_seen",
    "nfd_in_cntrs0",
    "nfd_in_gather_debug_queue_state0",
    "nfd_in_gather_debug_state0",
    "nfd_in_halt_wq_mem",
    "nfd_in_pd_debug_state0",
    "nfd_in_tx_sent0",
    "nfd_init_done",
    "nfd_init_done_atomic",
    "nfd_out_atomics0",
    "nfd_out_cacher_dbg0",
    "nfd_out_cacher_qdbg0",
    "nfd_out_cntrs0",
    "nfd_out_ring_mem0",
    "nfd_out_sb_debug_state0",
    "nfd_out_sb_dma_done0",
    "nfd_out_sb_release0",
    "nfd_vf_cfg_max_vfs",
    "num_ov_alloc__cntr__",
    "num_ov_free__cntr__",
    "pkt_counters_base0",
    "pkt_counters_base1",
    "pkt_counters_base2",
    "pkt_counters_base3",
    "pkt_counters_base4",
    "pkt_counters_base5",
    "pkt_counters_base6",
    "sriov_journal_cmsg",
    "unroll_overflow_err__cntr__",
]

NbiXPB_to_dump = [
    "TrafficManager.SchedulerL1Deficit.SchedulerDeficit{0..1023}",
    "TrafficManager.SchedulerL1Weight.SchedulerWeight{0..1023}",
    "TrafficManager.SchedulerL2Deficit.SchedulerDeficit{0..1023}",
    "TrafficManager.SchedulerL2Weight.SchedulerWeight{0..1023}",

    "TrafficManager.TMQueueReg.QueueConfig{0..1023}",
    "TrafficManager.TMQueueReg.QueueDropCount{0..1023}",
    "TrafficManager.TMQueueReg.QueueStatus{0..1023}",

    "TrafficManager.TMSchedulerReg.SchedulerConfig{0..144}",
    "TrafficManager.TMSchedulerReg.SchedulerDeficit{0..127}",
    "TrafficManager.TMSchedulerReg.SchedulerWeight{0..127}",

    "TrafficManager.TMShaperReg.ShaperMaxOvershoot{0..144}",
    "TrafficManager.TMShaperReg.ShaperRate{0..144}",
    "TrafficManager.TMShaperReg.ShaperRateAdjust{0..144}",
    "TrafficManager.TMShaperReg.ShaperStatus{0..144}",
    "TrafficManager.TMShaperReg.ShaperThreshold{0..144}",

    "TrafficManager.TrafficManagerReg.BlqEvent",
    "TrafficManager.TrafficManagerReg.DropRate",
    "TrafficManager.TrafficManagerReg.EgressPullIdPortEnable",
    "TrafficManager.TrafficManagerReg.EgressRateLimit",
    "TrafficManager.TrafficManagerReg.MiniPktChannelCredit{0..127}",
    "TrafficManager.TrafficManagerReg.MiniPktCreditConfig",
    "TrafficManager.TrafficManagerReg.MiniPktFreePoolCredit0",
    "TrafficManager.TrafficManagerReg.MiniPktFreePoolCredit1",
    "TrafficManager.TrafficManagerReg.ReorderActivity",
    "TrafficManager.TrafficManagerReg.TrafficManagerConfig",

    "PktPreclassifier.Characterization.Config",
    "PktPreclassifier.Characterization.TableSet",
    "PktPreclassifier.Picoengine.PicoengineSetup",
    "PktPreclassifier.Picoengine.TableExtend",
    "PktPreclassifier.Picoengine.ActiveSet0Low",
    "PktPreclassifier.Picoengine.ActiveSet0High",
    "PktPreclassifier.Picoengine.ActiveSet1Low",
    "PktPreclassifier.Picoengine.ActiveSet1High",
    "PktPreclassifier.Picoengine.ClassifiedSmall",
    "PktPreclassifier.Picoengine.ClassifiedLarge",
    "PktPreclassifier.Picoengine.Tunnel",
    "PktPreclassifier.PolicerSequencer.Accumulator{0..7}",
    "PktPreclassifier.PolicerSequencer.Config",
    "PktPreclassifier.PolicerSequencer.Sequence{0..7}",
    ]

def parse_cmdline():
    """Use argparse to read command line variables."""
    parser = argparse.ArgumentParser(
        description='Collect various bits of debugging information')
    parser.add_argument(
        '-i',
        '--interface',
        dest='iface',
        nargs='?',
        action='store',
        default='',
        help="Optional - nfp netdev to collect information on")
    parser.add_argument(
        '-l',
        '--logdir',
        dest='logdir',
        action='store',
        default='/var/tmp',
        help="Optional - base directory to use for logs")

    args = parser.parse_args()

    # Verify arguments
    if args.iface:
        iface = args.iface
        if iface not in os.listdir("/sys/class/net"):
            print(f"{iface} not found on system")
            exit(1)
        with open(f"/sys/class/net/{iface}/device/vendor", "r") as vendor_f:
            vendor = vendor_f.read().strip()
            if vendor not in VENDOR_LIST:
                print(f"{iface} with vendor id: {vendor} is not "
                      "a valid nfp device")
                exit(1)

    return args

def get_nfps():
    """Return dict of NFP's on the system, key is the BDF."""
    # Walk /sys/bus/pci/devices - this removes the need to depend on
    # lspci being installed
    nfp_dict = {}
    devices = '/sys/bus/pci/devices'
    for root, dirs, files in os.walk(devices):
        for pci in dirs:
            with open(f"{root}/{pci}/vendor", "r") as vendor_f:
                vendor = vendor_f.read().strip()
                if vendor in VENDOR_LIST:
                    with open(f"{root}/{pci}/device", "r") as dev_f:
                        device = dev_f.read().strip()
                        if device in DEV_LIST:
                            nfp_dict[pci] = {}
    return nfp_dict

def check_bsp_tools_installed():
    """Check if bsp tools are installed on the system.
       Returns the path of the installation if found, else empty string
    """
    # Check if in path by checking "which"
    path = shutil.which("nfp-hwinfo")
    if path is not None:
        return os.path.dirname(path)

    # Otherwise check common path(s) for tools installation
    for path in BSP_PATHS:
        if os.path.exists(path) and "nfp-hwinfo" in os.listdir(path):
            return path

    return ""

def scmd(command, fail=True):
    """Run bash commands from python.

    Args:
        - command:    Command to execute
        - fail: Stops program if a command fails and prints debug info
    Return:
        A tuple with STDOUT, STDERR and the return code
    """
    global SCRIPT_LOG
    process = Popen(command, stdout=PIPE, stderr=PIPE, close_fds=False,
                    shell=True)

    stdoutdata, stderrdata = process.communicate()
    ret = process.returncode
    msg = f'CMD: {command}\n'
    msg += f'RET: {ret}\n'
    if ret != 0 and fail is True:
        msg += f'STDOUT:\n{stdoutdata.decode()}\n'
        msg += f'STDERR:\n{stderrdata.decode()}\n'
        if CONFIG_DEBUG_SCMD:
            print(msg)
        exit(1)
    if SCRIPT_LOG != '':
        with open(SCRIPT_LOG, 'a') as logf:
            logf.write(msg)

    return stdoutdata.decode(), stderrdata.decode(), ret

def bsp_comand(bsp_path, nfp_pci, bsp_cmd, options=""):
    """Helper to execute bsp commands"""
    cmd = f"{bsp_path}/{bsp_cmd} -Z {nfp_pci} {options}"
    out, err, ret = scmd(cmd, fail=False)
    return out, err, ret

def write_logfile(input_strings, filename, flags='w'):
    """Write strings log into corresponding file"""
    with open(filename, flags) as f:
        f.write(input_strings)

def common_data(outDir):
    """Output data that needs to be stored separately"""

    # Log firmware path where driver loads from. Could be symlinked files
    libFw, _, _ = scmd('ls -ogR --time-style="+" /lib/firmware/netronome/',
                       fail=False)
    libFw_path = f'{outDir}/lib_firmware.log'
    write_logfile(libFw, libFw_path)

    # Log firmware path where package installs places files
    optFw, _, _ = scmd('ls -ogR --time-style="+" /opt/firmware/netronome/',
                       fail=False)
    optFw_path = f'{outDir}/opt_firmware.log'
    write_logfile(optFw, optFw_path)

    nfp_pcis = get_nfps()
    nfp_pcis_path = f'{outDir}/nfp_pcis.log'
    write_logfile(str(nfp_pcis), nfp_pcis_path)

    for line in nfp_pcis:
        # Driver might not be bound to nfp, in which case none of the below
        # data can be gathered. Log this and move to next nfp pci device.
        if not os.path.exists(f'/sys/bus/pci/drivers/nfp/{line}/net'):
            no_ndev_log_path = f'{outDir}/{line}_no_netdevs'
            msg = f"No netdevs seem to exist for {line}. Most likely cause "
            msg += "is that the device is not bound to the nfp driver\n"
            write_logfile(msg, no_ndev_log_path)
            continue

        ndevs = "\n".join(os.listdir(f'/sys/bus/pci/drivers/nfp/{line}/net'))
        ndevs_path = f'{outDir}/ndevs.log'
        write_logfile(ndevs, ndevs_path, flags='a')
        ndev = os.listdir(f'/sys/bus/pci/drivers/nfp/{line}/net')[0]
        # set ethtool loglevel to 0
        scmd(f'ethtool -W {ndev} 0', fail=False)
        scmd(f'ethtool -w {ndev} data {outDir}/ethtool_{ndev}_debug_L0.dat',
             fail=False)
        # set ethtool loglevel to 1
        scmd(f'ethtool -W {ndev} 1', fail=False)
        scmd(f'ethtool -w {ndev} data {outDir}/ethtool_{ndev}_debug_L1.dat',
             fail=False)

    # devlink dev list
    dev_list, _, _ = scmd('devlink dev list', fail=False)
    dev_list_path = f'{outDir}/devlink_dev_list'
    write_logfile(dev_list, dev_list_path)

    with open(dev_list_path) as f:
        for port in f:
            port = port.replace('\n', '')
            pName = port.replace('/', '-')
            # devlink dev info <pci_address>
            dev_info, _, _ = scmd(f'devlink dev info {port}', fail=False)
            dev_info_path = f'{outDir}/devlink_dev_info_{pName}'
            write_logfile(dev_info, dev_info_path)

    # sensors
    sensors_info, _, _ = scmd('sensors -n', fail=False)
    sensors_path = f'{outDir}/sensors'
    write_logfile(sensors_info, sensors_path)

    # lspci
    lspci_info, _, _ = scmd('lspci -vvv', fail=False)
    lspci_path = f'{outDir}/lspci'
    write_logfile(lspci_info, lspci_path)

    # lspci - tree view
    lspci_tv_info, _, _ = scmd('lspci -tv', fail=False)
    lspci_tv_path = f'{outDir}/lspci_tv'
    write_logfile(lspci_tv_info, lspci_tv_path)

    # firewalld
    firewalld_info, _, _ = scmd('systemctl status firewalld', fail=False)
    firewalld_path = f'{outDir}/systemctl_status_firewalld'
    write_logfile(firewalld_info, firewalld_path)

    # irqbalance
    irqbalance_info, _, _ = scmd('systemctl status irqbalance', fail=False)
    irqbalance_path = f'{outDir}/systemctl_status_irqbalance'
    write_logfile(irqbalance_info, irqbalance_path)

    # lscpu
    lscpu_info, _, _ = scmd('lscpu', fail=False)
    lscpu_path = f'{outDir}/lscpu'
    write_logfile(lscpu_info, lscpu_path)

    # lshw
    lshw_info, _, _ = scmd('lshw -class network -businfo', fail=False)
    lshw_path = f'{outDir}/lshw'
    write_logfile(lshw_info, lshw_path)

    # /etc/*release
    etc_release_info, _, _ = scmd('ls -l /etc/*release && cat /etc/*release',
                                  fail=False)
    etc_release_path = f'{outDir}/etc_release'
    write_logfile(etc_release_info, etc_release_path)

    # numactl --hardware
    numactl_info, _, _ = scmd('numactl --hardware', fail=False)
    numactl_path = f'{outDir}/numactl_hardware'
    write_logfile(numactl_info, numactl_path)

    # The next two commands tries to capture the installed packages on
    # the system. Adding system detection that is stable accross all
    # OS's is complicated and error prone, so instead just log both
    # std_out and std_err for both 'rpm -qa' and 'dpkg -l'

    # rpm -qa
    rpm_info, err, _ = scmd('rpm -qa', fail=False)
    rpm_info += f"\n{err}"
    rpm_path = f'{outDir}/rpm_package_list'
    write_logfile(rpm_info, rpm_path)

    # dpkg -l
    deb_info, err, _ = scmd('dpkg -l', fail=False)
    deb_info += f"\n{err}"
    deb_path = f'{outDir}/deb_package_list'
    write_logfile(deb_info, deb_path)

    # dmidecode
    for dmi in ["bios", "system", "baseboard", "chassis", "processor",
                "memory", "cache", "connector", "slot"]:

        dmi_info, _, _ = scmd(f'dmidecode -t {dmi}', fail=False)
        dmi_path = f'{outDir}/dmidecode_{dmi}'
        write_logfile(dmi_info, dmi_path)

    # /proc/meminfo
    meminfo_path = f'{outDir}/proc_meminfo'
    try:
        shutil.copy2('/proc/meminfo', meminfo_path)
    except Exception:
        write_logfile('Error reading /proc/meminfo', meminfo_path)

    # /proc/cpuinfo
    cpuinfo_path = f'{outDir}/proc_cpuinfo'
    try:
        shutil.copy2('/proc/cpuinfo', cpuinfo_path)
    except Exception:
        write_logfile('Error reading /proc/cpuinfo', cpuinfo_path)

    # /var/boot.log
    bootlog_path = f'{outDir}/boot.log'
    try:
        shutil.copy2('/var/log/boot.log', bootlog_path)
    except Exception:
        write_logfile('Error reading /var/log/boot.log', bootlog_path)

    # history
    home_dir = os.path.expanduser('~')
    history_infile = f'{home_dir}/.bash_history'
    history_outfile = f'{outDir}/history'
    try:
        shutil.copy2(history_infile, history_outfile)
    except Exception:
        write_logfile(f'{history_infile}/ not found',
                      history_outfile)

    # /etc/udev/rules.d
    udev_indir = '/etc/udev/rules.d'
    udev_outdir = f'{outDir}/etc_udev_rules.d'
    try:
        shutil.copytree(udev_indir, udev_outdir)
    except Exception:
        os.makedirs(udev_outdir, exist_ok=True)
        write_logfile(f'Could not backup {udev_indir}\n',
                      f'{udev_outdir}/udev_rules.d_err')

    # /usr/lib/udev/rules.d
    udev_indir = '/usr/lib/udev/rules.d'
    udev_outdir = f'{outDir}/usr_lib_udev_rules.d'
    try:
        shutil.copytree(udev_indir, udev_outdir)
    except Exception:
        os.makedirs(udev_outdir, exist_ok=True)
        write_logfile(f'Could not backup {udev_indir}\n',
                      f'{udev_outdir}/usr_udev_rules.d_err')

    # /etc/sysconfig/network-scripts
    nscripts_indir = '/etc/sysconfig/network-scripts'
    nscripts_outdir = f'{outDir}/network-scripts'
    try:
        shutil.copytree(nscripts_indir, nscripts_outdir)
    except Exception:
        os.makedirs(nscripts_outdir, exist_ok=True)
        write_logfile(f'Could not backup {nscripts_indir}\n',
                      f'{nscripts_outdir}/nscripts_err')

def sos_data(outDir):
    """Output data from sos."""
    sos_cmd = get_sosreport_cmd()
    if sos_cmd == "":
        return False
    loaded_plugins = "-o networking -o logs -o kernel"
    loaded_plugins_path = f'{outDir}/loaded_plugins'
    write_logfile(f"{loaded_plugins}\n", loaded_plugins_path)
    # sos report -o networking -o logs -o kernel --batch --tmp-dir --build
    print("Generate DATA with sos")
    scmd(f'{sos_cmd} {loaded_plugins} --batch --tmp-dir {outDir} --build',
         fail=False)
    return True

def self_data(outDir):
    """Output data similar to sos but add self"""
    ethDir = f'{outDir}/ethtool'
    os.makedirs(ethDir, exist_ok=True)
    # ls /sys/class/net
    net_list, _, _ = scmd('ls /sys/class/net', fail=False)
    net_list_path = f'{ethDir}/net_list'
    write_logfile(net_list, net_list_path)

    with open(net_list_path) as f:
        for item in f:
            item = item.replace('\n', '')
            # ethtool <port>
            ethtool, _, _ = scmd(f'ethtool {item}', fail=False)
            ethtool_path = f'{ethDir}/ethtool_{item}'
            write_logfile(ethtool, ethtool_path)
            # ethtool -a <port>
            ethtool_a, _, _ = scmd(f'ethtool -a {item}', fail=False)
            ethtool_a_path = f'{ethDir}/ethtool_-a_{item}'
            write_logfile(ethtool_a, ethtool_a_path)
            # ethtool -c <port>
            ethtool_c, _, _ = scmd(f'ethtool -c {item}', fail=False)
            ethtool_c_path = f'{ethDir}/ethtool_-c_{item}'
            write_logfile(ethtool_c, ethtool_c_path)
            # ethtool -d <port>
            ethtool_d, _, _ = scmd(f'ethtool -d {item}', fail=False)
            ethtool_d_path = f'{ethDir}/ethtool_-d_{item}'
            write_logfile(ethtool_d, ethtool_d_path)
            # ethtool -k <port>
            ethtool_k, _, _ = scmd(f'ethtool -k {item}', fail=False)
            ethtool_k_path = f'{ethDir}/ethtool_-k_{item}'
            write_logfile(ethtool_k, ethtool_k_path)
            # ethtool -i <port>
            ethtool_i, _, _ = scmd(f'ethtool -i {item}', fail=False)
            ethtool_i_path = f'{ethDir}/ethtool_-i_{item}'
            write_logfile(ethtool_i, ethtool_i_path)
            # ethtool -P <port>
            ethtool_P, _, _ = scmd(f'ethtool -P {item}', fail=False)
            ethtool_P_path = f'{ethDir}/ethtool_-P_{item}'
            write_logfile(ethtool_P, ethtool_P_path)
            # ethtool --phy-statistics <port>
            ethtool_phy_s, _, _ = scmd(f'ethtool --phy-statistics {item}',
                                       fail=False)
            ethtool_phy_s_path = f'{ethDir}/ethtool_-phy-statistics_{item}'
            write_logfile(ethtool_phy_s, ethtool_phy_s_path)
            # ethtool -S <port>
            ethtool_S, _, _ = scmd(f'ethtool -S {item}', fail=False)
            ethtool_S_path = f'{ethDir}/ethtool_-S_{item}'
            write_logfile(ethtool_S, ethtool_S_path)
            # ethtool -g <port>
            ethtool_g, _, _ = scmd(f'ethtool -g {item}', fail=False)
            ethtool_g_path = f'{ethDir}/ethtool_-g_{item}'
            write_logfile(ethtool_g, ethtool_g_path)
            # ethtool -T <port>
            ethtool_T, _, _ = scmd(f'ethtool -T {item}', fail=False)
            ethtool_T_path = f'{ethDir}/ethtool_-T_{item}'
            write_logfile(ethtool_T, ethtool_T_path)
            # ethtool -m <port>
            ethtool_m, _, _ = scmd(f'ethtool -m {item}', fail=False)
            ethtool_m_path = f'{ethDir}/ethtool_-m_{item}'
            write_logfile(ethtool_m, ethtool_m_path)
            # ethtool --show-eee <port>
            ethtool_show_eee, _, _ = scmd(f'ethtool --show-eee {item}',
                                          fail=False)
            ethtool_show_eee_path = f'{ethDir}/ethtool_-show-eee_{item}'
            write_logfile(ethtool_show_eee, ethtool_show_eee_path)
            # ethtool --show-fec <port>
            ethtool_show_fec, _, _ = scmd(f'ethtool --show-fec {item}',
                                          fail=False)
            ethtool_show_fec_path = f'{ethDir}/ethtool_-show-fec_{item}'
            write_logfile(ethtool_show_fec, ethtool_show_fec_path)
            # ethtool --show-priv-flags <port>
            ethtool_show_priv, _, _ = scmd(f'ethtool --show-priv-flags {item}',
                                           fail=False)
            ethtool_priv_path = f'{ethDir}/ethtool_-show-priv-flags_{item}'
            write_logfile(ethtool_show_priv, ethtool_priv_path)
            # tc -s filter show dev <port>
            tc_filter, _, _ = scmd(f'tc -s filter show dev {item}', fail=False)
            tc_filter_path = f'{ethDir}/tc_-s_filter_{item}'
            write_logfile(tc_filter, tc_filter_path)
            # tc -s filter show dev <port> ingress
            tc_ingress, _, _ = scmd(f'tc -s filter show dev {item} ingress',
                                    fail=False)
            tc_ingress_path = f'{ethDir}/tc_-s_filter_{item}_ingress'
            write_logfile(tc_ingress, tc_ingress_path)

    # nstat -zas
    nstat_zas, _, _ = scmd('nstat -zas', fail=False)
    nstat_zas_path = f'{ethDir}/nstat_-zas'
    write_logfile(nstat_zas, nstat_zas_path)
    # netstat -W -neopa
    netstat_W_neopa, _, _ = scmd('netstat -W -neopa', fail=False)
    netstat_W_neopa_path = f'{ethDir}/netstat_-W_-neopa'
    write_logfile(netstat_W_neopa, netstat_W_neopa_path)
    # netstat -W -agn
    netstat_W_agn, _, _ = scmd('netstat -W -agn', fail=False)
    netstat_W_agn_path = f'{ethDir}/netstat_-W_-agn'
    write_logfile(netstat_W_agn, netstat_W_agn_path)
    # netstat -s
    netstat_s, _, _ = scmd('netstat -s', fail=False)
    netstat_s_path = f'{ethDir}/netstat_s'
    write_logfile(netstat_s, netstat_s_path)
    # ip -s neigh show
    ip_s_neigh_show, _, _ = scmd('ip -s neigh show', fail=False)
    ip_s_neigh_show_path = f'{ethDir}/ip_-s_neigh_show'
    write_logfile(ip_s_neigh_show, ip_s_neigh_show_path)
    # ip -s -d link
    ip_sd_link, _, _ = scmd('ip -s -d link', fail=False)
    ip_sd_link_path = f'{ethDir}/ip_-s_-d_link'
    write_logfile(ip_sd_link, ip_sd_link_path)
    # ip route show table all
    ip_r_show_tb, _, _ = scmd('ip route show table all', fail=False)
    ip_r_show_tb_path = f'{ethDir}/ip_route_show_table_all'
    write_logfile(ip_r_show_tb, ip_r_show_tb_path)
    # ip -o addr
    ip_o_addr, _, _ = scmd('ip -o addr', fail=False)
    ip_o_addr_path = f'{ethDir}/ip_-o_addr'
    write_logfile(ip_o_addr, ip_o_addr_path)
    # ip netns
    ip_netns, _, _ = scmd('ip netns', fail=False)
    ip_netns_path = f'{ethDir}/ip_netns'
    write_logfile(ip_netns, ip_netns_path)
    # ip neigh show nud noarp
    ip_nshow_nud, _, _ = scmd('ip neigh show nud noarp', fail=False)
    ip_nshow_nud_path = f'{ethDir}/ip_neigh_show_nud_noarp'
    write_logfile(ip_nshow_nud, ip_nshow_nud_path)
    # ip mroute show
    ip_mroute, _, _ = scmd('ip mroute show', fail=False)
    ip_mroute_path = f'{ethDir}/ip_mroute_show'
    write_logfile(ip_mroute, ip_mroute_path)
    # ip maddr show
    ip_maddr, _, _ = scmd('ip maddr show', fail=False)
    ip_maddr_path = f'{ethDir}/ip_maddr_show'
    write_logfile(ip_maddr, ip_maddr_path)
    # ip -d route show cache
    ip_droute, _, _ = scmd('ip -d route show cache', fail=False)
    ip_droute_path = f'{ethDir}/ip_-d_route_show_cache'
    write_logfile(ip_droute, ip_droute_path)
    # ip -d address
    ip_daddr, _, _ = scmd('ip -d address', fail=False)
    ip_daddr_path = f'{ethDir}/ip_-d_address'
    write_logfile(ip_daddr, ip_daddr_path)
    # ip -d -6 route show cache
    ip_d6route, _, _ = scmd('ip -d -6 route show cache', fail=False)
    ip_d6route_path = f'{ethDir}/ip_-d_-6_route_show_cache'
    write_logfile(ip_d6route, ip_d6route_path)
    # ip -6 rule
    ip_6_rule, _, _ = scmd('ip -6 rule', fail=False)
    ip_6_rule_path = f'{ethDir}/ip_-d_-6_route_show_cache'
    write_logfile(ip_6_rule, ip_6_rule_path)
    # ip -6 route show table all
    ip_6_route_tb, _, _ = scmd('ip -6 route show table all', fail=False)
    ip_6_route_tb_path = f'{ethDir}/ip_-6_route_show_table_all'
    write_logfile(ip_6_route_tb, ip_6_route_tb_path)
    # ip -4 rule
    ip_4_rule, _, _ = scmd('ip -4 rule', fail=False)
    ip_4_rule_path = f'{ethDir}/ip_-4_rule'
    write_logfile(ip_4_rule, ip_4_rule_path)
    # ifenslave -a
    ifenslave_a, _, _ = scmd('ifenslave -a', fail=False)
    ifenslave_a_path = f'{ethDir}/ifenslave_-a'
    write_logfile(ifenslave_a, ifenslave_a_path)

    knlDir = f'{outDir}/kernel'
    os.makedirs(knlDir, exist_ok=True)
    # cat /etc/hostname
    etc_hostname, _, _ = scmd('cat /etc/hostname', fail=False)
    etc_hostname_path = f'{knlDir}/etc_hostname.log'
    write_logfile(etc_hostname, etc_hostname_path)
    # journalctl -k
    journalctl_k, _, _ = scmd('journalctl -k', fail=False)
    journalctl_k_path = f'{knlDir}/journalctl_-k.log'
    write_logfile(journalctl_k, journalctl_k_path)
    # uname -a
    uname_a, _, _ = scmd('uname -a', fail=False)
    uname_a_path = f'{knlDir}/uname_-a.log'
    write_logfile(uname_a, uname_a_path)
    # cat /etc/*release
    etc_release, _, _ = scmd('cat /etc/*release', fail=False)
    etc_release_path = f'{knlDir}/etc_release.log'
    write_logfile(etc_release, etc_release_path)
    # modinfo nfp
    modinfo_nfp, _, _ = scmd('modinfo nfp', fail=False)
    modinfo_nfp_path = f'{knlDir}/modinfo_nfp.log'
    write_logfile(modinfo_nfp, modinfo_nfp_path)
    # lsmod
    lsmod, _, _ = scmd('lsmod', fail=False)
    lsmod_path = f'{knlDir}/lsmod.log'
    write_logfile(lsmod, lsmod_path)
    # cat /proc/cmdline
    cmdline, _, _ = scmd('cat /proc/cmdline', fail=False)
    cmdline_path = f'{knlDir}/cmdline.log'
    write_logfile(cmdline, cmdline_path)
    # ls /sys/bus/pci/drivers/nfp/module/parameters/
    oot_para_path = '/sys/bus/pci/drivers/nfp/module/parameters/'
    oot_parameters, _, _ = scmd(f'ls {oot_para_path}', fail=False)
    oot_parameters_path = f'{knlDir}/oot_parameters.log'
    write_logfile(oot_parameters, oot_parameters_path)
    # cat /boot/config-$(uname -r)
    kernel_config, _, _ = scmd('cat /boot/config-$(uname -r)', fail=False)
    kernel_config_path = f'{knlDir}/kernel_config.log'
    write_logfile(kernel_config, kernel_config_path)

    if 'CentOS' in etc_release:
        # lsinitrd
        lsinitrd, _, _ = scmd('lsinitrd', fail=False)
        lsinitrd_path = f'{knlDir}/lsinitrd.log'
        write_logfile(lsinitrd, lsinitrd_path)
    elif 'Ubuntu' in etc_release:
        # sinitramfs /boot/initrd.img
        lsinitramfs, _, _ = scmd('lsinitramfs /boot/initrd.img', fail=False)
        lsinitramfs_path = f'{knlDir}/lsinitramfs.log'
        write_logfile(lsinitramfs, lsinitramfs_path)

def check_cpp_access(outDir):
    """Checks if the driver was loaded with cpp access enabled"""
    cpp_param = 0
    bspDir = f'{outDir}/bsp_logs'
    os.makedirs(bspDir, exist_ok=True)

    nfp_module_path = '/sys/bus/pci/drivers/nfp/module'
    cpp_param_path = f'{nfp_module_path}/parameters/nfp_dev_cpp'

    # Check if in-tree driver is loaded
    if not os.path.exists(cpp_param_path):
        fail_msg_path = f'{bspDir}/fail_intree_module'
        message = f'{nfp_module_path} does not exist\n'
    else:
        with open(cpp_param_path) as cpp_file:
            cpp_param = cpp_file.read()
        cpp_param = int(cpp_param)
        if cpp_param == 0:
            fail_msg_path = f'{bspDir}/fail_cpp_not_enabled'
            message = "driver not loaded with cpp_access enabled\n"

    # Check if driver is loaded at all, and override error
    # message if not loaded
    if not os.path.exists(nfp_module_path):
        fail_msg_path = f'{bspDir}/fail_module_not_loaded'
        message = f'{nfp_module_path} missing, driver not loaded or built-in\n'

    # If cpp_param did not get set write to log and exit
    if cpp_param == 0:
        write_logfile(message, fail_msg_path)
        return False
    return True

def filter_multi_pf(pci_list):
    """Returns a filtered list, containing only single pci-address
    for every card.

    Entries in list is in the normal DBDF <0000:aa:00.0>.
    If there are multi-PF devices then there will be two (or more)
    entries for a card, e.g:
        0000:aa:00.0
        0000:aa:00.1

    This function will return a list containing only one entry per
    card.
    """

    # This will be the new returned list
    filt_pci = []
    # This list is temporary to keep track of previously seen devices
    BDF_list = []

    for pci in pci_list:
        BDF = pci.split('.')[0]
        if BDF not in BDF_list:
            BDF_list.append(BDF)
            filt_pci.append(pci)
    return filt_pci

def netdev_to_pci(netdev):
    """Takes in a netdev name, and returns an pci-address if possible,
    otherwise None
    """
    try:
        pci_path = os.readlink(f'/sys/class/net/{netdev}/device')
        pci_path = os.path.basename(pci_path)
        return pci_path
    except Exception:
        return None

def get_enabled_islands(bsp_path, pci):
    """Parses 'chip.island' and return list of enabled islands"""

    isl_list = []
    out, _, _ = bsp_comand(bsp_path, pci, 'nfp-hwinfo', options='chip.island')
    isl_hex_str = out.split('=')[1]
    # isl_hex_str in format '0x1001f13000112'
    isl_int = int(isl_hex_str, 16)

    # Bit positions correspond with enabled islands, convert to binary
    # representation in order to parse
    isl_bin_str = "{:b}".format(isl_int)
    for nr, me in enumerate(isl_bin_str[::-1]):
        if me == '1':
            isl_list.append(nr)
    return isl_list

def parse_rtsym_table(sym_str):
    """Parses the output of the 'nfp-rtsym -L' command
        Name                    Resource   Address      Size
        BLM_EMU_RING_INIT_CHK_0 <generic>  0x0000000000 0x0000000001
        nfd_in_ring_nums0       <generic>  0x0000000000 0x0000000001

    Returns a dictionary of dictionaries:
        { "BLM_EMU..." :
            { "Resource": <generic>,
              "Address": 0x000...,
              "Size": int(0x000...),
            },
          "nfd_in...":
          {
          }
        }
    """
    rtsym_dict = {}
    # Iterate through lines, but skip the heading
    for line in sym_str.strip().split("\n")[1:]:
        name, res, addr, size = line.strip().split()
        rtsym_dict[name] = {
            "Resource": res,
            "Address": addr,
            "Size": int(size, 16)
            }
    return rtsym_dict

def filter_xpb_nbi(xpb_in):
    """Dumping ALL the nbi xpb/m information takes very long and does
    sometime leave the card in a bad state. Limit to only specific
    information and return a list of commands.
    """
    nbi_cmd_list = []
    for nbiXPB in NbiXPB_to_dump:
        cmd = f'{xpb_in}NbiTopXpbMap.{nbiXPB}'
        nbi_cmd_list.append(cmd)

    return nbi_cmd_list

def write_rtsym(bsp_path, pci, rtsym_dict, key, logpath):
    """Simple wrapper to log rtsym command"""
    head = f'rtsym={key},size={rtsym_dict[key]["Size"]}\n'
    write_logfile(head, logpath, "a")
    dat, _, _ = bsp_comand(bsp_path, pci, 'nfp-rtsym', options=f'-v {key}')
    write_logfile(dat, logpath, "a")

def collect_bsp_data(bsp_path, outDir, args):
    """Collect low level debug information using BSP tools"""

    bspDir = f"{outDir}/bsp_logs"
    os.makedirs(bspDir, exist_ok=True)
    all_nfp_pcis = get_nfps()
    nfp_pcis = filter_multi_pf(all_nfp_pcis)

    # Collect generic BSP info for all nfp's
    for pci in nfp_pcis:
        # Each entry a tuple of the command to run [0], and the option
        # flags to use [1]
        cmds = (
            ('nfp-arm', '-D'),
            ('nfp-fis', '-b1 list'),
            ('nfp-hwinfo', ''),
            ('nfp-media', ''),
            ('nfp-nsp', '-E'),
            ('nfp-phymod', ''),
            ('nfp-res', '-L'),
            ('nfp-temp', ''),
            ('nic-power', ''),
        )
        for cmd, opt in cmds:
            out, _, _ = bsp_comand(bsp_path, pci, cmd, options=opt)
            fpath = f"{bspDir}/{pci}_{cmd}"
            # If option is specified add this to the output filename
            if opt:
                fpath = f"{fpath}_{opt}"
            out_str = f"{out.strip()}\n"
            write_logfile(out_str, fpath, "w")

        # Log the enabled NFP islands
        isls = get_enabled_islands(bsp_path, pci)
        fpath = f"{bspDir}/{pci}_islands"
        out_str = (",".join(ISL_MAP[x][0] for x in isls))
        out_str += "\n"
        write_logfile(out_str, fpath, "w")

        # Check if gearbox is in use, and log additional info
        hwinfo, _, _ = bsp_comand(bsp_path, pci, 'nfp-hwinfo', options='')
        hwinfo_d = {}
        for line in hwinfo.strip().split('\n'):
            key, val = line.strip().split('=')
            hwinfo_d[key] = val

        if 'phy0.mvl5113' in hwinfo_d.keys():
            # Get nr of ports:
            port_count = 0
            for k in hwinfo_d.keys():
                if '.nbi' in k:
                    port_count += 1

            # Log mdio commands
            fpath = f"{bspDir}/{pci}_mdio"
            cmd_list = [
                '7.0000',  # Lane Auto-Negotiation Control
                '7.0001',  # Lane Auto-Negotiation Status
                '7.0010',  # Auto-Negotiation Advertisement Register 1
                '7.0011',  # Auto-Negotiation Advertisement Register 2
                '7.0012',  # Auto-Negotiation Advertisement Register 3
                '3.F000',  # Laneside Interface Mode Select Sub Port 0
                '4.F000',  # Hostside Interface Mode Select Sub Port 0
                ]
            data = ''
            for mdio_cmd in cmd_list:
                for port_nr in range(0, port_count):
                    cmd = f'2 {port_nr} {mdio_cmd}'
                    out, _, _ = bsp_comand(bsp_path, pci, 'nfp-mdio',
                                           options=cmd)
                    data = f'{data}nfp-mdio {cmd}={out}\n'
            write_logfile(data, fpath, "a")

    # Collect firmware specific logs if the interface was specified, otherwise
    # return now
    netdev = args.iface
    if netdev == '':
        return

    # Exit early if the device is not in the pci id list
    ndev_pci = netdev_to_pci(netdev)
    if ndev_pci is None or ndev_pci not in all_nfp_pcis:
        print(f"{ndev_pci} for {netdev} does not seem to be in"
              f"the detected nfp devices: {all_nfp_pcis.keys()}")
        return
    print(f'Collecting low level information for {netdev}, pci:{ndev_pci}')

    # ME_csr dumps
    MECSRS = [
        "ActCtxStatus",
        "CtxEnables",
        "CSRCtxPtr",
        "UstorErrStat",
        "ALUOut",
        "CtxArbCtrl",
        "CondCodeEn",
        "RegErrStatus",
        "LMErrStatus",
        "LMeccErrorMask",
    ]

    isls = get_enabled_islands(bsp_path, ndev_pci)
    for isl in isls:
        nr_mes = ISL_MAP[isl][1]
        if nr_mes == 0:
            continue

        fpath = f"{bspDir}/{ndev_pci}_{netdev}_MECSRS"
        data = ''
        for MECSR in MECSRS:
            me_str = f"i{isl}.me{{0..{nr_mes - 1}}}"
            cmd = f'mecsr:{me_str}.{MECSR}'
            # e.g: cmd=mecsr:i1.me{0..3}.CtxEnables
            out, _, _ = bsp_comand(bsp_path, ndev_pci, 'nfp-reg', options=cmd)
            data = f'{data}{out}\n'
        write_logfile(data, fpath, "w")

        # While in this loop also collect cls information
        fpath = f"{bspDir}/{ndev_pci}_{netdev}_cls"
        cmd = f'cls:i{isl}'
        out, _, _ = bsp_comand(bsp_path, ndev_pci, 'nfp-reg', options=cmd)
        write_logfile(out, fpath, "a")

    # Collect xpb and xpbm information.
    for xpb_cmd in ['xpb', 'xpbm']:
        # Get list of valid targets. The output needs some filtering as some
        # duplication is present
        out, _, _ = bsp_comand(bsp_path, ndev_pci, 'nfp-reg',
                               options=f"-l {xpb_cmd}")

        # Iterate through output lines, and only add to list if not already
        # present. Also filter out some of the commands that takes a long time.
        cmd_list = []
        for line in out.split():
            cmd = line.strip()
            # Skip all Nbi xpbm commands
            if "Nbi" in cmd and xpb_cmd == 'xpbm':
                continue
            # Filter Nbi xpb commands
            elif "Nbi" in cmd and xpb_cmd == 'xpb':
                cmd_list += filter_xpb_nbi(cmd)
            # Add all other commands
            elif cmd not in cmd_list:
                cmd_list.append(cmd)

        # Execute commands from the list and log to file
        for xpb in cmd_list:
            fpath = f"{bspDir}/{ndev_pci}_{netdev}_{xpb_cmd.upper()}Map"
            out, _, _ = bsp_comand(bsp_path, ndev_pci, 'nfp-reg',
                                   options=f"{xpb}")
            write_logfile(out, fpath, "a")

    # Collect rtsym information
    out, _, _ = bsp_comand(bsp_path, ndev_pci, 'nfp-rtsym', options="-L")
    rtsym_dict = parse_rtsym_table(out)

    fpath = f'{bspDir}/{ndev_pci}_{netdev}_rtsyms'
    for sym in rtsyms_to_dump:
        if sym in rtsym_dict.keys():
            write_rtsym(bsp_path, ndev_pci, rtsym_dict, sym, fpath)

def get_sosreport_cmd():
    """ Check for the existance of either 'sos' or 'sosreport'

    Return 'sos report' if tool is 'sos'
    Return 'sosreport' if tools is 'sosreport'
    Return empty string if neither was found
    """

    # Try 'sosreport'
    sos_path = shutil.which("sosreport")
    if sos_path is not None:
        return sos_path

    # Try 'sos'
    sos_path = shutil.which("sos")
    if sos_path is not None:
        return f"{sos_path} report"

    return ""

def main():
    """Call the main program functions."""
    global SCRIPT_LOG

    args = parse_cmdline()

    missing_tools = []
    for tool in REQ_SHELL_TOOLS:
        if shutil.which(tool) is None:
            missing_tools.append(tool)
    if missing_tools:
        print(f"Missing tools: {', '.join(missing_tools)}\n"
              "Please ensure these are installed on the system.")
        exit(1)

    baseDir = os.path.abspath(args.logdir)
    date, _, _ = scmd('date -u +%Y.%m.%d.%H%M')
    date = date.replace('\n', '')
    outDir = f'{baseDir}/nfp_troubleshoot_gather_{date}'
    try:
        os.makedirs(outDir, exist_ok=True)
    except PermissionError:
        print(f'Error: Seems like {baseDir} does not have write permissions. '
              'Exiting.')
        exit(1)
    SCRIPT_LOG = f'{outDir}/script_cmds.log'

    is_root = False
    if os.getuid() == 0:
        is_root = True

    if is_root is False:
        print('Warn: It is recommended to run the script with root access. '
              'Some information will not be logged without root permissions.')
        with open(SCRIPT_LOG, 'a') as logf:
            logf.write('Script NOT executed as root\n')

    common_data(outDir)
    if not sos_data(outDir):
        print("sos is not installed. Suggest install")
        print("Generate DATA without sos")
        self_data(outDir)

    # BSP tools require sudo access, only execute if running as superuser
    if is_root is True:
        bsp_path = check_bsp_tools_installed()
        if bsp_path != '' and check_cpp_access(outDir):
            collect_bsp_data(bsp_path, outDir, args)

    # Tarring up logs
    # Clear SCRIPT_LOG, since this last step cannot be logged
    # while --remove-files is used with tar
    SCRIPT_LOG = ''
    scmd(f'tar -zcvf {outDir}.tar.gz -C {baseDir} '
         f'nfp_troubleshoot_gather_{date} --remove-files')
    print(f'Done: {outDir}.tar.gz')

    # If script was run as sudo try and set permissions. Use same permissions
    # as logdir
    if is_root is True:
        stat_info = os.stat(baseDir)
        uid = stat_info.st_uid
        gid = stat_info.st_gid
        os.chown(f'{outDir}.tar.gz', uid, gid)

if __name__ == "__main__":
    main()


# chat/urls.py
# root: /recipes/
from django.urls import path

from . import views

urlpatterns = [
    path('', views.recipe_small_start, name="recipe_small_start"),
    path('small/', views.recipe_small, name='recipe_small'),
    path('large/', views.recipe_large, name='recipe_large'),
    path('<str:room_name>/', views.room, name='room'),

]


import argparse
import asyncio
from sys import exit

from .proto import Client

def do_stats(caller, options):
    res = yield from caller.send_command('stats')
    if isinstance(res, Exception):
        print(res)
        exit(1)
    print(res.data.decode('ascii'))

def do_stats_tube(caller, options):
    for tube in options.tube:
        res = yield from caller.send_command('stats-tube', tube)
        if isinstance(res, Exception):
            print(res)
            exit(1)
        print(res.data.decode('ascii'))

@asyncio.coroutine
def run(options):
    conn = [('localhost', 11300)]
    if options.connect:
        conn = [(h, int(p))
                for h, p in (a.split(':', 1)
                             for a in options.connect)]
    assert len(conn) == 1, 'Only single connection supported so far'
    cli = yield from Client.connect(*conn[0])
    yield from options.action(cli, options)

def main():
    common = argparse.ArgumentParser(add_help=False)
    common.add_argument('-c', '--connect', metavar="HOST:PORT",
        help="Add beanstalkd server to connect to (repeatable)",
        default=[], action="append")
    ap = argparse.ArgumentParser(parents=[common])
    sub = ap.add_subparsers()

    sap = sub.add_parser("stats", parents=[common])
    sap.set_defaults(action=do_stats)

    tap = sub.add_parser("tube", parents=[common],
        aliases=['stats-tube', 'queue', 'stats-queue'])
    tap.add_argument("tube", metavar="NAME", default=["default"], nargs='*')
    tap.set_defaults(action=do_stats_tube)

    options = ap.parse_args()

    asyncio.get_event_loop().run_until_complete(run(options))

if __name__ == '__main__':
    from .stats import main  # flake8: noqa
    main()


# A part of NonVisual Desktop Access (NVDA)
# Copyright (C) 2006-2019 NV Access Limited
# This file is covered by the GNU General Public License.
# See the file COPYING for more details.

"""
When working on this file, consider moving to winAPI.
"""

import threading
from ctypes import *
from ctypes.wintypes import *
import watchdog
import winUser

# Some Windows constants
HC_ACTION = 0
WH_KEYBOARD_LL = 13
LLKHF_UP = 128
LLKHF_EXTENDED = 1
LLKHF_INJECTED = 16
WH_MOUSE_LL = 14
LLMHF_INJECTED = 1

class KBDLLHOOKSTRUCT(Structure):
	_fields_=[
		('vkCode',DWORD),
		('scanCode',DWORD),
		('flags',DWORD),
		('time',DWORD),
		('dwExtraInfo',DWORD),
	]

class MSLLHOOKSTRUCT(Structure):
	_fields_=[
		('pt',POINT),
		('mouseData',DWORD),
		('flags',DWORD),
		('time',DWORD),
		('dwExtraInfo',DWORD),
	]

keyDownCallback=None
keyUpCallback=None
mouseCallback=None

@WINFUNCTYPE(c_long,c_int,WPARAM,LPARAM)
def keyboardHook(code,wParam,lParam):
	if code != HC_ACTION:
		return windll.user32.CallNextHookEx(0,code,wParam,lParam)
	kbd=KBDLLHOOKSTRUCT.from_address(lParam)
	if keyUpCallback and kbd.flags&LLKHF_UP:
		if not keyUpCallback(kbd.vkCode,kbd.scanCode,bool(kbd.flags&LLKHF_EXTENDED),bool(kbd.flags&LLKHF_INJECTED)):
			return 1
	elif keyDownCallback:
		if not keyDownCallback(kbd.vkCode,kbd.scanCode,bool(kbd.flags&LLKHF_EXTENDED),bool(kbd.flags&LLKHF_INJECTED)):
			return 1
	return windll.user32.CallNextHookEx(0,code,wParam,lParam)

@WINFUNCTYPE(c_long,c_int,WPARAM,LPARAM)
def mouseHook(code,wParam,lParam):
	if watchdog.isAttemptingRecovery or code!=HC_ACTION:
		return windll.user32.CallNextHookEx(0,code,wParam,lParam)
	msll=MSLLHOOKSTRUCT.from_address(lParam)
	if mouseCallback:
		if not mouseCallback(wParam,msll.pt.x,msll.pt.y,msll.flags&LLMHF_INJECTED):
			return 1
	return windll.user32.CallNextHookEx(0,code,wParam,lParam)

hookThread=None
hookThreadRefCount=0

def hookThreadFunc():
	keyHookID=windll.user32.SetWindowsHookExW(WH_KEYBOARD_LL,keyboardHook,windll.kernel32.GetModuleHandleW(None),0)
	if keyHookID==0:
		raise OSError("Could not register keyboard hook")
	mouseHookID=windll.user32.SetWindowsHookExW(WH_MOUSE_LL,mouseHook,windll.kernel32.GetModuleHandleW(None),0)
	if mouseHookID==0:
		raise OSError("Could not register mouse hook")
	msg=MSG()
	while windll.user32.GetMessageW(byref(msg),None,0,0):
		pass
	if windll.user32.UnhookWindowsHookEx(keyHookID)==0:
		raise OSError("could not unregister key hook %s"%keyHookID)
	if windll.user32.UnhookWindowsHookEx(mouseHookID)==0:
		raise OSError("could not unregister mouse hook %s"%mouseHookID)

def initialize():
	global hookThread, hookThreadRefCount
	hookThreadRefCount+=1
	if hookThreadRefCount==1:
		hookThread = threading.Thread(
			name=__name__,  # winInputHook
			target=hookThreadFunc
		)
		hookThread.start()

def setCallbacks(keyUp=None,keyDown=None,mouse=None):
	global keyUpCallback, keyDownCallback, mouseCallback
	if keyUp:
		keyUpCallback=keyUp
	if keyDown:
		keyDownCallback=keyDown
	if mouse:
		mouseCallback=mouse

def terminate():
	global hookThread, hookThreadRefCount
	if not hookThread:
		raise RuntimeError("winInputHook not running")
	hookThreadRefCount-=1
	if hookThreadRefCount==0:
		windll.user32.PostThreadMessageW(hookThread.ident,winUser.WM_QUIT,0,0)
		hookThread.join()
		hookThread=None


import RPi.GPIO as GPIO
import time
from readchar import readchar
from gpiozero import Robot

#GPIO.cleanup()

GPIO.setmode(GPIO.BCM)                     #Set GPIO pin numbering

bit_a = 22
bit_b = 27
bit_c = 17
rf_pin = 15

GPIO.setup(bit_a, GPIO.OUT)
GPIO.setup(bit_b, GPIO.OUT)
GPIO.setup(bit_c, GPIO.OUT)
GPIO.setup(rf_pin,GPIO.OUT)

leftPins_x = (12, 16)
rightPins_x = (20, 21)

leftPins_y = (26, 19)
rightPins_y = (13, 6)

robot_x = Robot(left = leftPins_x, right = rightPins_x)
robot_y = Robot(left = leftPins_y, right = rightPins_y)

def robot_con(xl, xr, yl, yr):
    robot_x.value = (xl, xr)
    robot_y.value = (yl, yr)

def robot_con2(x, y):
    robot_x.value = (x, x)
    robot_y.value = (y, y)

def multiplex(code):

    if len(code) == 3:

        GPIO.output(bit_a, int(code[2]))
        GPIO.output(bit_b, int(code[1]))
        GPIO.output(bit_c, int(code[0]))
        time.sleep(0.001)

    else:
        print("multiplex fail")

def distancesen(echo_pin, trig_pin):

    GPIO.setup(trig_pin,GPIO.OUT)                  #Set pin as GPIO out
    GPIO.setup(echo_pin,GPIO.IN)                   #Set pin as GPIO in

    GPIO.output(trig_pin, False)                 #Set TRIG as LOW
    GPIO.output(rf_pin, False)                  #rf is active low
    time.sleep(0.05)

    GPIO.output(trig_pin, True)                  #Set TRIG as HIGH
    time.sleep(0.00001)                      #Delay of 0.00001 seconds
    GPIO.output(trig_pin, False)                 #Set TRIG as LOW

    pulse_start = time.time()

    while GPIO.input(echo_pin)==0:               #Check whether the ECHO is LOW
        pulse_start = time.time()              #Saves the last known time of LOW pulse

    GPIO.output(rf_pin, True)

    pulse_end = time.time()

    while GPIO.input(echo_pin)==1:               #Check whether the ECHO is HIGH
        pulse_end = time.time()                #Saves the last known time of HIGH pulse

    pulse_duration = pulse_end - pulse_start #Get pulse duration to avariable
    distance = (pulse_duration-0.05) * 34030    #Multiply pulse duration by 17150 to get distance

    time.sleep(0.2)

    return round(distance, 2)            #Round to two decimal points

def multi_ultra(string, echo_pin, trig_pin):
    multiplex(string)
    return distancesen(echo_pin, trig_pin)

def ultra(element):
    if element == 1:
        return multi_ultra('000', 23, 24)
    elif element == 2:
        return multi_ultra('001', 23, 24)
    elif element == 3:
        return multi_ultra('010', 23, 24)
    elif element == 4:
        return multi_ultra('011', 23, 24)
    elif element == 5:
        return multi_ultra('100', 23, 24)
    elif element == 6:
        return multi_ultra('101', 23, 24)
    elif element == 7:
        return multi_ultra('110', 23, 24)
    elif element == 8:
        return multi_ultra('111', 23, 24)
    else:
        print("ultra fail")
        return None

def valid_dist(value):

    #print("check valid")
    attempts = 5

    for i in range(1,attempts +1):
        dist = ultra(value)
        #print(dist)
        if (0 < dist < 600):
            #i = attempts+10
            break
        else:
            #dist = None
            dist = 10000

    return dist

##while True:
##    #time.sleep(1)
##    #print "Distance measurement in progress"
##    #print "Waitng For Sensor To Settle"
##    distancesen(17, 27)
#------------------------------------------

def adj(module):
    if module == 1:
        list_module=[7,8,1,2,3]
    elif module == 2:
        list_module=[8,1,2,3,4]
    elif module == 3:
        list_module=[1,2,3,4,5]
    elif module == 4:
        list_module=[2,3,4,5,6]
    elif module == 5:
        list_module=[3,4,5,6,7]
    elif module == 6:
        list_module=[4,5,6,7,8]
    elif module == 7:
        list_module=[5,6,7,8,1]
    elif module == 8:
        list_module=[6,7,8,1,2]
    else:
        return None

    return list_module

def smart_al(module):
    #scan module

    #scan  adjacent
    adj_list = adj(module)
    #print(adj_list)
    dist_list = [0] * 5
    #print dist
    min_module = 10

    for i in range (0, len(adj_list)):
        #print(i, adj_list[i])
        dist_list[i] = valid_dist(adj_list[i])

    #print(dist_list)
    dist = min(dist_list)
    module = adj_list[dist_list.index(dist)]

    #if timeout, scan module 1

    return(module, dist)

multiplex('000')

#start = time.time()

print("***Starting***")

##while True:
##    num = 7
##    dist = ultra(num)
##    print(num,dist)

##while True:
##    for i in range(1,8):
##        dist = valid_dist(i)
##        print(i,dist)

module = 7

while True:
    dist = valid_dist(1)
    lower_lim = 100
    upper_lim = 200
    out_of_range = 400
    print(dist)
    if dist < lower_lim:
        #backward
        robot_con(-0.7, -0.7, 0, 0)
    elif upper_lim < dist < out_of_range:
        #forward
        robot_con(0.5, 0.5, 0, 0)
    else:
        #stop
        robot_con(0, 0, 0, 0)

#print(time.time() - start)


from initialize_phi import phi as ph
from schemes import  chanvesse_functional, yezzi_functional, bhattacharya_functional,seg_w_control,optimal_segmentation
import scipy.ndimage
class segmentation:

    def __init__(self, imname, algo,dt):
        self.imname = imname
        self.img = self.get_image()
        self.img_shape = self.img.shape
        self.algo = algo
        self.phi_obj = ph(img=self.img, shape=self.img_shape,mask=None)
        self.dt = dt

    def get_image(self):
        if self.imname == 'airplane':
            img = scipy.ndimage.imread('airplane.png')
        elif self.imname == 'zebra':
            img = scipy.ndimage.imread('zebra.bmp')
        elif self.imname == 'twoObj':
            img = scipy.ndimage.imread('twoObj.bmp')
        return img

    def execute(self):
        if self.algo == 'chanvesse':
            algo_obj = chanvesse_functional(img=self.img, phi_init=self.phi_obj, dt=self.dt)
            algo_obj.run_chanvesse()

        elif self.algo == 'yezzi':
            algo_obj = yezzi_functional(img=self.img, phi_init=self.phi_obj, dt=self.dt)
            algo_obj.run_yezzi()

        elif self.algo == 'bhattacharya':
            algo_obj = bhattacharya_functional(img=self.img, phi_init=self.phi_obj, dt=self.dt)
            algo_obj.run_bhattacharya()

        elif self.algo == 'ctrl':
            algo_obj = optimal_segmentation(img=self.img, phi_init=self.phi_obj, dt=self.dt)
            algo_obj.run_optimal_segmentation()

        elif self.algo == 'ctrl1':
            algo_obj = seg_w_control(img=self.img, phi_init=self.phi_obj, dt=self.dt)
            algo_obj.run()


"""
Main handler for plugin.video.edx
"""
import json
import urllib
import xbmc  # pylint: disable=import-error
import xbmcgui  # pylint: disable=import-error
import xbmcplugin  # pylint: disable=import-error

from resources.course import Course

def build_url(plugin_url, query):
    """
    Utility function for callbacks.
    """
    return plugin_url + '?' + urllib.urlencode(query)

def settings_error():
    """
    Show an error if required settings not present.
    """
    dialog = xbmcgui.Dialog()
    # i18n these strings!
    dialog.ok('edX Error', 'Error in edX configuration. Please ensure that username and password are valid. If you don\'t have an account, visit https://courses.edx.org/register to sign up and start learning!')  # pylint: disable=line-too-long

def file_location(key, extension=''):
    """
    Helper to construct a common location for files to be saved.
    """
    plugin_prefix = "plugin.video.edx"
    return "{0}{1}:{2}{3}".format(
        xbmc.translatePath('special://temp'),
        plugin_prefix,
        key,
        extension
    )

def write_tree(key, values):
    """
    Writes a course tree to temp storage, 1 layer at a time
    This allows for quick loading of submenus
    """
    values_to_write = []
    for val in values:
        if 'children' in val:
            values_to_write.append(
                {
                    'id': val['id'],
                    'name': val['name'],
                    'children': True
                }
            )
            write_tree(val['id'], val['children'])
        else:
            values_to_write.append(val)
            stream_file = file_location(key, '.strm')
            with open(stream_file, 'w+') as write_file:
                write_file.write(val['url'])
    with open(file_location(key), 'w+') as write_file:
        write_file.write(json.dumps(values_to_write))

def refresh_course_structure(client):
    """
    Refreshes the course structure stored on disk.

    Returns an id, name tuple for each of the top-level courses.
    """
    # init progress dialog
    progress = xbmcgui.DialogProgress()

    # setup client with access token
    progress.create('edX', "Asking server for access token...")
    client.get_access_token()

    # fetch list of courses
    progress.update(5, "Fetching course list...")
    courses = Course.build_from_results(client.get_courses())

    # simple progress: 1 op for get_access_token, get_courses, and each course
    current_progress = 2  # get_access_token and get_courses
    max_progress = (2 + len(courses))

    # per course, build directory structure
    ids = []
    for course in courses:
        progress.update(
            current_progress * 100 / max_progress,
            "Fetching course data for " + course.name
        )
        blocks, root_id = client.get_course_blocks(course.api_url)
        tree = course.build_tree(blocks, root_id)
        ids.append((tree['id'], tree['name']))

        # serialize
        write_tree(root_id, tree['children'])

        # update progress
        current_progress = current_progress + 1

    progress.close()
    return ids

def handle(mode, key, client, plugin_handle, base_url):
    """
    Main handling logic for plugin
    """
    if mode == None:  # First load
        courses = refresh_course_structure(client)

        # add top-level entries to current dir listing
        for c_id, c_name in courses:
            url = build_url(base_url, {'mode':'folder', 'cur_key': c_id})
            list_item = xbmcgui.ListItem(c_name)
            xbmcplugin.addDirectoryItem(
                handle=plugin_handle,
                url=url,
                listitem=list_item,
                isFolder=True
            )

        xbmcplugin.endOfDirectory(plugin_handle)

    elif mode[0] == 'folder':
        # We're in a folder
        folder_path = file_location(key[0])
        with open(folder_path, 'r') as read_file:
            values = json.loads(read_file.read())
        for val in values:
            if 'children' in val:
                url = build_url(base_url, {'mode':'folder', 'cur_key': val['id']})
                list_item = xbmcgui.ListItem(val['name'])
                xbmcplugin.addDirectoryItem(
                    handle=plugin_handle,
                    url=url,
                    listitem=list_item,
                    isFolder=True
                )
            else:
                list_item = xbmcgui.ListItem(val['name'])
                list_item.setProperty('IsPlayable', 'true')
                url = build_url(base_url, {'mode': 'play', 'cur_key': val['id']+'.strm'})
                xbmcplugin.addDirectoryItem(
                    handle=plugin_handle,
                    url=val['url'],
                    listitem=list_item,
                    isFolder=False
                )
        xbmcplugin.endOfDirectory(plugin_handle)

    elif mode[0] == 'play':
        play_item = xbmcgui.ListItem(path=key[0])
        xbmcplugin.setResolvedUrl(plugin_handle, True, listitem=play_item)


import unittest

import dbus
from unittest import mock

from rhsmlib.dbus import service_wrapper, constants

class ServiceWrapperTest(unittest.TestCase):
    def test_parse_argv(self):
        opts, args = service_wrapper.parse_argv(
            ["cmd_name", "--verbose", "--bus-name", "Hello", "Foo"], "Default"
        )
        self.assertTrue(opts.verbose)
        self.assertEqual(opts.bus_name, "Hello")
        self.assertEqual(args, ["Foo"])

    def test_uses_default_bus_name(self):
        opts, args = service_wrapper.parse_argv(["cmd_name", "Foo"], "Default")
        self.assertFalse(opts.verbose)
        self.assertEqual(opts.bus, dbus.SystemBus)
        self.assertEqual(opts.bus_name, "Default")
        self.assertEqual(args, ["Foo"])

    def test_loads_bus_given(self):
        opts, args = service_wrapper.parse_argv(["cmd_name", "--bus", "dbus.SessionBus", "Foo"], "Default")
        self.assertEqual(opts.bus, dbus.SessionBus)

    @mock.patch("rhsmlib.dbus.service_wrapper.server.Server")
    def test_loads_an_object_class(self, mock_serve):
        # Just use some class we have available
        service_wrapper.main(["cmd_name", "unittest.mock.MagicMock"])
        mock_serve.assert_called_with(
            bus_class=dbus.SystemBus, bus_name=constants.BUS_NAME, object_classes=[mock.MagicMock]
        )

    @mock.patch("rhsmlib.dbus.service_wrapper.server.Server")
    def test_loads_from_an_array_of_classes(self, mock_serve):
        service_wrapper.main(["cmd_name"], [mock.MagicMock])
        mock_serve.assert_called_with(
            bus_class=dbus.SystemBus, bus_name=constants.BUS_NAME, object_classes=[mock.MagicMock]
        )


#!/usr/bin/env python

import socket,os,sys,re,threading,inotify,time,ind

class wpaclass:
	def __init__(self):
		self.bssid = ""
		self.ssid = ""
		self.keymgmt = ""
		self.state = ""
		self.ip = ""
		self.qual = ""
		self.sock = None
		self.fnmap={'bssid':self.setbssid,
			    'ssid':self.setssid,
			    'key_mgmt':self.setkeymgmt,
			    'wpa_state':self.setstate,
			    'ip_address':self.setip,
			    'qual':self.setqual}
		return
	def setbssid(self,bssid):
		if bssid != self.bssid:
			self.bssid = bssid
			if self.sock:
				self.sock.send("BSS %s" % bssid)
				self.runparse()
	def runparse(self):
		try:
			data = self.sock.recv(65535)
		except:
			try:
				self.sock.send("PING")
			except:
				pass
			try:
				data = self.sock.recv(65535)
			except:
				self.setstate("DISCONNECTED")
				return
		splitdata = re.split("[\r\n]+",data)
		for line in splitdata:
			try:
				key,data = re.split("=",line)
			except ValueError:
				if re.search("CTRL-EVENT-CONNECTED",line):
					self.sock.send("STATUS")
					self.runparse()
				continue
			if key in self.fnmap:
				self.fnmap[key](data)

	def setssid(self,ssid):
		self.ssid = ssid
	def setkeymgmt(self,mgmt):
		self.keymgmt = mgmt
	def setstate(self,state):
		self.state = state
		if state != "COMPLETED":
			self.bssid=""
			self.ssid=""
			self.keymgmt = ""
			self.ip = ""
			self.qual = ""
			ind.n.set_from_file("icon/wifi0.png")
	def setip(self,ip):
		self.ip = ip
		self.setqual(self.qual)
	def setqual(self,qual):
		self.qual = qual
		qual = int(qual,10)
		if self.ip == "":
			ind.n.set_from_file("icon/wifi0.png")
		elif qual < 25:
			ind.n.set_from_file("icon/wifi1.png")
		elif qual < 50:
			ind.n.set_from_file("icon/wifi2.png")
		elif qual < 75:
			ind.n.set_from_file("icon/wifi3.png")
		else:
			ind.n.set_from_file("icon/wifi4.png")
	def __str__(self):
		return "%s: \nssid: %s\nqual: %s\naddr: %s\nproto: %s" % (self.state, self.ssid, self.qual, self.ip, self.keymgmt)
	def __repr__(self):
		return str(self)
	def doconnect(self,path):
		try:
			if not self.sock:
				self.sock =socket.socket(socket.AF_UNIX,socket.SOCK_DGRAM,0)
				self.sock.bind("/tmp/%d" % os.getpid())
			self.sock.connect(path)
			self.sock.send("ATTACH")
			self.sock.send("STATUS")
			self.sock.settimeout(1)
			self.runparse()
		except:
			time.sleep(0.5)
			self.doconnect(path)
	def lackingData(self):
		if self.state != "COMPLETED":
			return None
		if not self.ip or not self.qual or not self.bssid:
			return 1
		if not self.ssid or not self.keymgmt:
			return 1
wpamon = wpaclass()
def establish():
	wpamon.doconnect("/var/run/wpa_supplicant/wlan0")
establish()
th = threading.Thread(target=inotify.initwatch,kwargs={'callback':establish})
th.start()
while 1:
	wpamon.runparse()
	ind.n.set_tooltip_text(str(wpamon))
	if wpamon.lackingData():
		time.sleep(1) ## Limit how often we'll update
		wpamon.sock.send("STATUS")
wpamon.sock.shutdown(socket.SHUT_RDWR)
os.remove("/tmp/%d" % os.getpid())


# -*- coding: utf-8 -*-
from django import template
from django.utils.translation import ugettext_lazy as _

register = template.Library()

@register.filter
def arraylookup(a, idx):
    """
    Gets a value from an iterable.
    :param a: array / list / other monad.
    :param idx: aray index (zero based).
    :return: element, or None if not found.
    """
    if not a:
        return None
    elif len(a) <= idx:
        return None
    else:
        return a[idx]

@register.filter
def selectplan(plan):
    """
    Add the word "select" (i18n translated) before the label of the radio button.
    Hence <plan name> becomes "select <plan name>".
    :param plan: widget
    :return: modified version of the input, with the word "select" pasted before its label.
    """
    if hasattr(plan, "choice_label"):
        plan.choice_label = _("select {}".format(plan.choice_label))
    return plan


'''
This program estimates pi by considering a unit circle enclosed a square.
In order to estimate pi, the hit and miss method was employed, we consider
a 2 x 2 square piece of paper with an inscribed circle of radius 1, we then simulate throwing
darts at the sqaure and we have the following relations:

    (number of dots inside circle)/(total number of dots) = (area of circle)/(area of square)

13 May 2019
Bruce Mvubele

'''

import numpy as np
import matplotlib.pyplot as plt
import numpy.random as random

# Create x and y variable for the dots consisting of random numbers
# this will be the simulation of dart throwing
y = random.uniform(-1,1,150)
x = random.uniform(-1,1,150)

#create Circle
r = 1 # radius of circle
thetha = np.arange(0,2*np.pi,.01) # angular variable
circle_x = r*np.cos(thetha)
circle_y = r*np.sin(thetha)

# Plot the simulation
plt.plot(circle_x,circle_y)
plt.scatter(x,y)
plt.show()

# number of dots inside circle
inside = 0

i = 0
q = 0
darts = 150

#Finding number of dots in circle
for i in range(0,darts):
    x = x**2
    y = y**2
    if np.sqrt(np.any(x) + np.any(y)) < 1 :
        inside = inside + 1

print(f'Number of dots inside the circle is {inside} out of a total of {darts}')
pi = (float(inside)/150) *4
print(f'pi \u2248 {pi}')
print(f'error = {abs(np.pi - pi)}')

# for statistical purposes we can do the simulation 5 times and take the
# average as the best estimate
# #Extracted pi estimates
# pi_est = [3.546,3.466,3.573,3.520,3.530]
# print('pi avge', np.sum(pi_est)/5)
# mean = np.mean(pi_est)
# var = np.var(pi_est)
# std = np.sqrt(np.var(pi_est))

# print('mean =', mean)
# print('standard deviation =', std)


import pyopencl as cl
import numpy as np
import cv2
import os
import sys
import time
import pickle
import numpy as np
from math import atan2, floor, pi
from skimage.metrics import peak_signal_noise_ratio

def get_elapsed_ms(ev_list):
    elapsed = []
    for e in ev_list:
        elapsed.append((e.profile.end - e.profile.start) / 1000000)
    return elapsed

class ClRaisr:
    workGroupSize = (16, 16)
    cscRgb2yuv = np.array([
        0.299, 0.587, 0.114, 0,
        -0.14713, -0.28886, 0.436, 0,
        0.615, -0.51499, -0.10001, 0,
        0, 0, 0, 1
    ], dtype=np.float32)
    cscYuv2rgb = np.array([
        1, 0, 1.13983, 0,
        1, -0.39465, -0.58060, 0,
        1, 2.03211, 0, 0,
        0, 0, 0, 1
    ], dtype=np.float32)
    cscYuv2yuv = np.array([
        1, 0, 0, 0,
        0, 1, 0, 0,
        0, 0, 1, 0,
        0, 0, 0, 1
    ], dtype=np.float32)
    sobelX = np.array([
        -1, 0, 1,
        -2, 0, 2,
        -1, 0, 1,
    ], dtype=np.float32)
    sobelY = np.array([
        -1, -2, -1,
        0, 0, 0,
        1, 2, 1
    ], dtype=np.float32)
    def gaussian2d(self, shape=(3,3),sigma=0.5):
        """
        2D gaussian mask - should give the same result as MATLAB's
        fspecial('gaussian',[shape],[sigma])
        """
        m,n = [(ss-1.)/2. for ss in shape]
        y,x = np.ogrid[-m:m+1,-n:n+1]
        h = np.exp( -(x*x + y*y) / (2.*sigma*sigma) )
        h[ h < np.finfo(h.dtype).eps*h.max() ] = 0
        sumh = h.sum()
        if sumh != 0:
            h /= sumh
        return h

    def __init__(self, grayMode):
        os.environ['PYOPENCL_COMPILER_OUTPUT'] = '1'
        os.environ['PYOPENCL_NO_CACHE'] = '1'
        self.grayMode = grayMode
        for p in cl.get_platforms():
            if 'AMD' in p.name:
                devices = p.get_devices(device_type=cl.device_type.GPU)
                if len(devices) > 0:
                    self.dev = devices[0]
                    self.ctx = cl.Context(dev_type=cl.device_type.GPU, properties=[(cl.context_properties.PLATFORM, p)])
                    self.queue = cl.CommandQueue(self.ctx, properties=cl.command_queue_properties.PROFILING_ENABLE)
                    filepath = os.path.split(os.path.realpath(__file__))[0]
                    with open(os.path.join(filepath, 'raisr.cl'), 'r') as f:
                        kernSrc = f.read()
                        self.prg = cl.Program(self.ctx, kernSrc).build(options = ' -DWORK_GROUP_WIDTH={} -DWORK_GROUP_HEIGHT={} '.format(self.workGroupSize[1], self.workGroupSize[0]))
        with open(os.path.join(filepath, 'filter.p'), 'rb') as fp:
            self.filters_x2 = pickle.load(fp).astype(np.float32)

        self.gaussian = self.gaussian2d([9, 9], 2)
        self.gaussian = np.diag(self.gaussian.ravel()).astype(np.float32)
        self.gaussian = np.diag(self.gaussian).copy()
        self.kern = self.prg.raisr

    def upsample(self, src, dst, scale_factor):
        srcw = src.shape[1]
        srch = src.shape[0]
        dstw = dst.shape[1]
        dsth = dst.shape[0]
        if scale_factor == 2:
            filters = self.filters_x2
        else:
            print('Fatal. not trained for scale factor {}'.format(scale_factor))
            return

        mf = cl.mem_flags
        if self.grayMode == 1:
            fmt = cl.ImageFormat(cl.channel_order.R, cl.channel_type.UNORM_INT8)
            clCscToYuv = cl.Buffer(self.ctx, mf.READ_ONLY | mf.USE_HOST_PTR, hostbuf=self.cscYuv2yuv)
            clCscFromYuv = cl.Buffer(self.ctx, mf.READ_ONLY | mf.USE_HOST_PTR, hostbuf=self.cscYuv2yuv)
        else:
            fmt = cl.ImageFormat(cl.channel_order.BGRA, cl.channel_type.UNORM_INT8)
            clCscToYuv = cl.Buffer(self.ctx, mf.READ_ONLY | mf.USE_HOST_PTR, hostbuf=self.cscRgb2yuv)
            clCscFromYuv = cl.Buffer(self.ctx, mf.READ_ONLY | mf.USE_HOST_PTR, hostbuf=self.cscYuv2rgb)
        clSrcImg = cl.Image(self.ctx, mf.READ_ONLY, fmt, shape=(srcw, srch))
        clDstImg = cl.Image(self.ctx, mf.WRITE_ONLY, fmt, shape=(dstw, dsth))

        clSobelX = cl.Buffer(self.ctx, mf.READ_ONLY | mf.USE_HOST_PTR, hostbuf=self.sobelX)
        clSobelY = cl.Buffer(self.ctx, mf.READ_ONLY | mf.USE_HOST_PTR, hostbuf=self.sobelY)
        clGaussian = cl.Buffer(self.ctx, mf.READ_ONLY | mf.USE_HOST_PTR, hostbuf=self.gaussian)
        clFilters = cl.Buffer(self.ctx, mf.READ_ONLY | mf.USE_HOST_PTR, hostbuf=filters)
        npStreQuantizer = np.array([0.0001, 0.001], dtype=np.float32)
        clStreQ = cl.Buffer(self.ctx, mf.READ_ONLY | mf.USE_HOST_PTR, hostbuf=npStreQuantizer)
        npCoheQuantizer = np.array([0.25, 0.5], dtype=np.float32)
        clCoheQ = cl.Buffer(self.ctx, mf.READ_ONLY | mf.USE_HOST_PTR, hostbuf=npCoheQuantizer)

        self.kern.set_args( \
            clSrcImg, \
            clDstImg, \
            clSobelX, \
            clSobelY, \
            clCscToYuv, \
            clCscFromYuv, \
            clGaussian, \
            clStreQ, \
            clCoheQ, \
            np.int32(scale_factor), \
            clFilters \
        )
        ev0 = cl.enqueue_copy(self.queue, clSrcImg, src, origin=(0, 0), region=(srcw, srch))
        ev1 = cl.enqueue_nd_range_kernel(self.queue, self.kern, (dstw, dsth), (self.workGroupSize[1], self.workGroupSize[0]), wait_for=[ev0])
        ev2 = cl.enqueue_copy(self.queue, dst, clDstImg, origin=(0, 0), region=(dstw, dsth), wait_for=[ev1])
        ev2.wait()

        return get_elapsed_ms([ev0, ev1, ev2])

if __name__ == '__main__':

    imgGray = 0

    raisr = ClRaisr(imgGray)

    refHR = cv2.imread('images/Set5/img_001_SRF_2_HR.png')
    wHR = refHR.shape[1]
    hHR = refHR.shape[0]
    #bgr = cv2.resize(refHR, (wHR//2, hHR//2))
    bgr = cv2.imread('images/Set5/img_001_SRF_2_LR.png')
    w = bgr.shape[1]
    h = bgr.shape[0]
    #wHR = 2 * w
    #hHR = 2 * h
    refUp = cv2.resize(bgr, (wHR, hHR), interpolation=cv2.INTER_LINEAR)

    loopcount = 20
    count = 0

    if imgGray == 1:
        ycrcb = cv2.cvtColor(bgr, cv2.COLOR_BGR2YCrCb)
        ycrcb_dst = cv2.resize(ycrcb, (wHR, hHR), interpolation=cv2.INTER_LINEAR)
        src = ycrcb[:,:,0].copy()
        dst = np.zeros((hHR, wHR), dtype=src.dtype)
    else:
        src = cv2.cvtColor(bgr, cv2.COLOR_BGR2BGRA)
        dst = np.zeros((hHR, wHR, 4), dtype=np.uint8)

    elapsed_list = None
    while count < loopcount:
        elapsed = raisr.upsample(src, dst, 2)
        if elapsed_list is None:
            elapsed_list = elapsed
        else:
            for i in range(len(elapsed)):
                elapsed_list[i] += elapsed[i]
        count += 1

    if imgGray == 1:
        ycrcb_dst[:,:,0] = dst
        dst = cv2.cvtColor(ycrcb_dst, cv2.COLOR_YCrCb2BGR)

    cv2.imwrite('raisr-out.png', dst)
    cv2.imwrite('raisr-ref-upsample.png', refUp)
    print('elapsed: {:.3f} + {:.3f} + {:.3f} ms'.format(elapsed_list[0]/count, elapsed_list[1]/count, elapsed_list[2]/count))

    psnrCubic = peak_signal_noise_ratio(refUp, refHR, data_range=255)
    psnrRaisr = peak_signal_noise_ratio(dst[:,:,0:3], refHR, data_range=255)
    print('PSNR: cubic {:.3f} raisr {:.3f}'.format(psnrCubic, psnrRaisr))


from __future__ import annotations

from typing import Any, Iterable, List, Optional, Type, Union

from eth_typing import URI
from typing_extensions import Protocol
from web3 import HTTPProvider
from web3.types import RPCEndpoint, RPCResponse
from ankr.exceptions import APIError

class MultichainHTTPProvider(HTTPProvider):
    def __init__(
        self,
        api_key: str,
        endpoint_uri: Optional[Union[URI, str]] = None,
        request_kwargs: Optional[Any] = None,
        session: Optional[Any] = None,
    ) -> None:
        endpoint_uri = endpoint_uri or "https://rpc.ankr.com/multichain/"
        super().__init__(endpoint_uri + api_key, request_kwargs, session)

    def clean_nones(self, value):
        """
        Recursively remove all None values from dictionaries and lists, and returns
        the result as a new dictionary or list.
        """
        if isinstance(value, list):
            return [self.clean_nones(x) for x in value if x is not None]
        elif isinstance(value, dict):
            return {
                key: self.clean_nones(val)
                for key, val in value.items()
                if val is not None
            }
        else:
            return value

    def make_request(self, method: RPCEndpoint, params: Any) -> RPCResponse:
        response = super().make_request(
            method, self.clean_nones(params.to_dict().copy())
        )
        if response.get("error"):
            raise APIError(response["error"])
        if "result" not in response:
            raise APIError("returned no result")
        return response

    def call_method(
        self,
        rpc: str,
        request: Any,
        reply: Any,
    ) -> Any:
        response = self.make_request(RPCEndpoint(rpc), request)
        reply = reply.from_dict(**response["result"])
        return reply

    def call_method_paginated(
        self,
        *,
        rpc: str,
        request: Any,
        reply: Any,
        iterable_name: str,
        iterable_type: Type[Any],
        limit: Optional[int] = None,
    ) -> Iterable[Any]:
        response = self.make_request(RPCEndpoint(rpc), request)
        reply = reply.from_dict(**response["result"])

        items: List[Any] = getattr(reply, iterable_name) or []

        if limit:
            if limit <= len(items):
                yield from items[:limit]
                return
            limit -= len(items)

        yield from items

        if reply.nextPageToken:
            request.pageToken = reply.nextPageToken
            yield from self.call_method_paginated(
                rpc=RPCEndpoint(rpc),
                request=request,
                reply=reply,
                iterable_name=iterable_name,
                iterable_type=iterable_type,
                limit=limit,
            )

class TProviderConstructor(Protocol):
    def __call__(
        self, api_key: Optional[str] = None, request_kwargs: Optional[Any] = None
    ) -> HTTPProvider:
        ...

def http_provider_constructor(url: str) -> TProviderConstructor:
    def init(
        api_key: Optional[str] = None,
        request_kwargs: Optional[Any] = None,
    ) -> HTTPProvider:
        if api_key is None:
            api_key = ""
        return HTTPProvider(f"{url}/{api_key}", request_kwargs)

    return init

# EVM
ArbitrumHTTPProvider = http_provider_constructor("https://rpc.ankr.com/arbitrum")
AvalancheHTTPProvider = http_provider_constructor("https://rpc.ankr.com/avalanche")
BscHTTPProvider = http_provider_constructor("https://rpc.ankr.com/bsc")
CeloHTTPProvider = http_provider_constructor("https://rpc.ankr.com/celo")
EthHTTPProvider = http_provider_constructor("https://rpc.ankr.com/eth")
FantomHTTPProvider = http_provider_constructor("https://rpc.ankr.com/fantom")
GnosisHTTPProvider = http_provider_constructor("https://rpc.ankr.com/gnosis")
HarmonyHTTPProvider = http_provider_constructor("https://rpc.ankr.com/harmony")
IotexHTTPProvider = http_provider_constructor("https://rpc.ankr.com/iotex")
MoonbeamHTTPProvider = http_provider_constructor("https://rpc.ankr.com/moonbeam")
NervosHTTPProvider = http_provider_constructor("https://rpc.ankr.com/nervos")
OptimismHTTPProvider = http_provider_constructor("https://rpc.ankr.com/optimism")
PolygonHTTPProvider = http_provider_constructor("https://rpc.ankr.com/polygon")
SyscoinHTTPProvider = http_provider_constructor("https://rpc.ankr.com/syscoin")

# Non-EVM
NearHTTPProvider = http_provider_constructor("https://rpc.ankr.com/near")
SolanaHTTPProvider = http_provider_constructor("https://rpc.ankr.com/solana")


import math
import random
from matplotlib import pyplot as plt
import time

def f(rjesenje, tezinska_matrica):
    put = 0
    put += tezinska_matrica[rjesenje[0] - 1][rjesenje[1] - 1]
    for i in range(1, len(rjesenje) - 1):
        put += tezinska_matrica[rjesenje[i] - 1][rjesenje[i + 1] - 1]
    put += tezinska_matrica[rjesenje[len(rjesenje) - 1] - 1][rjesenje[0] - 1]
    return put

def pocetno_rjesenje(tezinska_matrica):
    i = 0
    brojac = 0
    posjeceni = [0]
    while brojac < len(tezinska_matrica) - 1:
        brojac += 1
        bez_nula = [x for x in tezinska_matrica[i]]
        for k in range(len(bez_nula)):
            if k in posjeceni:
                bez_nula[k] = 0
        bez_nula = [x for x in bez_nula if x > 0]
        minimalni = min(bez_nula)
        for j in range(len(tezinska_matrica)):
            if tezinska_matrica[i][j] == minimalni:
                pamti_j = j
                posjeceni.append(pamti_j)
                break
        i = pamti_j
    for m in range(len(posjeceni)):
        posjeceni[m] += 1
    return posjeceni

def greedy(tezine,pocetnaTacka):
    konacnaLista=[pocetnaTacka]
    oznacenePozicije=[pocetnaTacka]
    i=pocetnaTacka
    for brojac in range(1,len(tezine)):
        trenutneTezine=[x for x in tezine[i]]
        for j in range(len(trenutneTezine)):
            if(j in oznacenePozicije):
                trenutneTezine[j]=0
        trenutneTezine=[x for x in trenutneTezine if x != 0]
        if(len(trenutneTezine)==0):
            break
        minimum=min(trenutneTezine)
        trenutneTezine=[x for x in tezine[i]]
        indeksMinimuma=trenutneTezine.index(minimum)
        konacnaLista.append(indeksMinimuma)
        oznacenePozicije.append(indeksMinimuma)
        i=indeksMinimuma
    return konacnaLista

def funkcijaCilja(cvorovi,tezine):
    pocetni=cvorovi[0]
    sljedeci=cvorovi[1]
    suma=0
    for i in range(1,len(cvorovi)):
        sljedeci=cvorovi[i]
        suma=suma+tezine[pocetni][sljedeci]
        pocetni=sljedeci
    suma=suma+tezine[pocetni][cvorovi[0]]
    return suma

def KonstruirajRjesenje(alfa,beta,tau,tezinskaMatrica):
    i=random.choice(range(len(tezinskaMatrica)))
    rjesenje=[i]
    for brojac in range(len(tezinskaMatrica)-1):
        dozvoljenaOkolina=[]
        for broj in range(0,len(tezinskaMatrica)):
            dozvoljenaOkolina.append(broj)
        dozvoljenaOkolina=[x for x in dozvoljenaOkolina if x not in rjesenje]
        vjerovatnocaGrane=[]
        for broj in range(0,len(tezinskaMatrica)):
            vjerovatnocaGrane.append(0)
        nazivnik=0
        for l in dozvoljenaOkolina:
            nazivnik+=pow(tau[i][l],alfa)*pow((1/tezinskaMatrica[i][l]),beta)
        for j in dozvoljenaOkolina:
            eta=1/tezinskaMatrica[i][j]
            brojnik=pow(tau[i][j],alfa)*pow(eta,beta)
            if(nazivnik!=0):
                vjerovatnocaGrane[j]=brojnik/nazivnik
        maksimum=max(vjerovatnocaGrane)
        indeksMaksimuma=vjerovatnocaGrane.index(maksimum)
        i=indeksMaksimuma
        rjesenje.append(i)
    return rjesenje

def IsparavanjeFeromonskogTraga(tau,ro):
    for i in range(len(tau)):
        for j in range(len(tau[i])):
            tau[i][j]*=(1-ro)
    return tau

def plot(cvorovi,rjesenje,line_width=1, point_radius=math.sqrt(2.0), annotation_size=8, dpi=120):
        x = [cvorovi[i][0] for i in rjesenje]
        x.append(x[0])
        y = [cvorovi[i][1] for i in rjesenje]
        y.append(y[0])
        plt.plot(x, y, linewidth=line_width)
        plt.scatter(x, y, s=math.pi * (point_radius ** 2.0))
        plt.title("Nadjeno rjesenje GA")
        for i in rjesenje:
            plt.annotate(i, cvorovi[i], size=annotation_size)
        plt.show()

def elitistickiACO(f,x0,tezinskaMatrica,brojMrava,brojIteracija,alfa,beta,ro,e):
    xZvijezda=[]
    vZvijezda=float("inf")
    tau=[]
    v0=f(x0,tezinskaMatrica)
    pocetnoTau=(e+brojMrava)/(ro*v0)
    for i in range(len(tezinskaMatrica)):
        lista=[]
        for j in range(len(tezinskaMatrica[i])):
            if(i!=j):
                lista.append(pocetnoTau)
            else:
                lista.append(0)
        tau.append(lista)

    while(brojIteracija>0):
        omegaPrim=[]
        omegaV=[]
        for k in range(brojMrava):
            xPrim=KonstruirajRjesenje(alfa,beta,tau,tezinskaMatrica)
            vPrim=f(xPrim,tezinskaMatrica)
            if(vPrim<vZvijezda):
                xZvijezda=xPrim
                vZvijezda=vPrim
            omegaPrim.append(xPrim)
            omegaV.append(f(xPrim,tezinskaMatrica))
        tau=[x for x in IsparavanjeFeromonskogTraga(tau,ro)]
        for i in range(len(omegaPrim)):
            xP=omegaPrim[i]
            for j in range(len(xP)-1):
                tau[xP[j]][xP[j+1]]+=1.0/omegaV[i]
                tau[xP[j+1]][xP[j]]+=1.0/omegaV[i]
            tau[xP[j]][xP[0]]+=1.0/omegaV[i]
            tau[xP[0]][xP[j]]+=1.0/omegaV[i]

        for j in range(len(xZvijezda)-1):
            tau[xZvijezda[j]][xZvijezda[j+1]]+=e/vZvijezda
            tau[xZvijezda[j+1]][xZvijezda[j]]+=e/vZvijezda
        tau[xZvijezda[j]][xZvijezda[0]]+=e/vZvijezda
        tau[xZvijezda[0]][xZvijezda[j]]+=e/vZvijezda
        brojIteracija-=1
    return (xZvijezda,vZvijezda)

def ACO(f,x0,tezinskaMatrica,brojMrava,brojIteracija,alfa,beta,ro):
    xZvijezda=[]
    vZvijezda=float("inf")
    tau=[]
    v0=f(x0,tezinskaMatrica)
    pocetnoTau=brojMrava/v0
    for i in range(len(tezinskaMatrica)):
        lista=[]
        for j in range(len(tezinskaMatrica[i])):
            if(i!=j):
                lista.append(pocetnoTau)
            else:
                lista.append(0)
        tau.append(lista)

    while(brojIteracija>0):
        omegaPrim=[]
        omegaV=[]
        for k in range(brojMrava):
            xPrim=KonstruirajRjesenje(alfa,beta,tau,tezinskaMatrica)
            vPrim=f(xPrim,tezinskaMatrica)
            if(vPrim<=vZvijezda):
                xZvijezda=xPrim
                vZvijezda=vPrim
            omegaPrim.append(xPrim)
            omegaV.append(f(xPrim,tezinskaMatrica))
        tau=[x for x in IsparavanjeFeromonskogTraga(tau,ro)]
        for i in range(len(omegaPrim)):
            xP=omegaPrim[i]
            for j in range(len(xP)-1):
                tau[xP[j]][xP[j+1]]+=1.0/omegaV[i]
                tau[xP[j+1]][xP[j]]+=1.0/omegaV[i]
            tau[xP[j]][xP[0]]+=1.0/omegaV[i]
            tau[xP[0]][xP[j]]+=1.0/omegaV[i]
        brojIteracija-=1
    return (xZvijezda,vZvijezda)

def konstruisi_rjesenje(tezinska_matrica, matrica_feromonski_trag, alfa, beta):
    brojac = 0
    posjeceni = [random.choice(range(len(tezinska_matrica)))]
    l = posjeceni[0]
    while brojac < len(tezinska_matrica) - 1:
        brojac += 1
        bez_nula = [x for x in tezinska_matrica[l]]
        for k in range(len(bez_nula)):
            if k in posjeceni:
                bez_nula[k] = 0
        suma = 0
        vjerovatnoce = [0] * len(bez_nula)
        for t in range(len(bez_nula)):
            if bez_nula[t] != 0:
                ni = 1/tezinska_matrica[l][t]
                suma += (pow(matrica_feromonski_trag[l][t], alfa) * pow(ni, beta))
        for r in range(len(bez_nula)):
            if bez_nula[r] != 0:
                ni = 1/tezinska_matrica[l][r]
                p = (pow(matrica_feromonski_trag[l][r], alfa) * pow(ni, beta))/suma
                vjerovatnoce[r] = p
        vjerovatnoce_bez_nula = [x for x in vjerovatnoce if x > 0]
        maksimalna_p = max(vjerovatnoce_bez_nula)
        for j in range(len(vjerovatnoce)):
            if vjerovatnoce[j] == maksimalna_p and j not in posjeceni:
                pamti_j = j
                posjeceni.append(pamti_j)
                break
        l = pamti_j
    for m in range(len(posjeceni)):
        posjeceni[m] += 1
    return posjeceni

def isparavanje_feromonskog_traga_MMAS(matrica_feromonski_trag, ro, Cbs):
    tau_max = 1/(ro * Cbs)
    tau_min = tau_max * 0.001
    for i in range(len(matrica_feromonski_trag)):
        for j in range(len(matrica_feromonski_trag)):
            if i != j:
                matrica_feromonski_trag[i][j] *= (1 - ro)
                if matrica_feromonski_trag[i][j] > tau_max:
                    matrica_feromonski_trag[i][j] = tau_max
                if matrica_feromonski_trag[i][j] < tau_min:
                    matrica_feromonski_trag[i][j] = tau_min
    return matrica_feromonski_trag

def azuriraj_feromonski_trag_MMAS(najbolje_rjesenje, tezinska_matrica, matrica_feromonski_trag, Cbs, ro):
    Ck = f(najbolje_rjesenje, tezinska_matrica)
    delta_tau = 1/Ck
    tau_max = 1/(ro * Cbs)
    tau_min = tau_max * 0.001
    for j in range(len(najbolje_rjesenje) - 1):
        matrica_feromonski_trag[najbolje_rjesenje[j] - 1][najbolje_rjesenje[j + 1] - 1] += delta_tau
        matrica_feromonski_trag[najbolje_rjesenje[j + 1] - 1][najbolje_rjesenje[j] - 1] += delta_tau
    matrica_feromonski_trag[najbolje_rjesenje[len(najbolje_rjesenje) - 1] - 1][najbolje_rjesenje[0] - 1] += delta_tau
    matrica_feromonski_trag[najbolje_rjesenje[0] - 1][najbolje_rjesenje[len(najbolje_rjesenje) - 1] - 1] += delta_tau
    return matrica_feromonski_trag

def reinicijaliziraj_MMAS(tezinska_matrica, matrica_feromonski_trag, Cbs, ro):
    tau_max = 1/(ro * Cbs)
    for i in range(len(matrica_feromonski_trag)):
        for j in range(len(matrica_feromonski_trag)):
            if i != j:
                matrica_feromonski_trag[i][j] = tau_max
                matrica_feromonski_trag[j][i] = tau_max
            else:
                matrica_feromonski_trag[i][j] = 0
    return matrica_feromonski_trag

def MMAS(alfa, beta, ro, tezinska_matrica, m, N, M):
    x_zvijezda = []
    v_zvijezda = float("inf")
    broj_iteracija = 0
    reincijaliziraj = 0

    pocetno = pocetno_rjesenje(tezinska_matrica)
    Cnn = f(pocetno, tezinska_matrica)
    x_min = pocetno
    v_min = Cnn
    tau0 = 1/(ro * Cnn)
    feromonski_trag = ([0] * len(tezinska_matrica))
    matrica_feromonski_trag = []

    #inicijalizacija feromonskog traga
    for i in range(len(feromonski_trag)):
        feromonski_trag = ([0] * len(tezinska_matrica))
        for j in range(len(feromonski_trag)):
            if i != j:
                feromonski_trag[j] = tau0
        matrica_feromonski_trag.append(feromonski_trag)

    while 1:
        broj_iteracija += 1
        omega = []
        putanje = []
        for i in range(m):

            #konstruisi rjesenje
            posjeceni = konstruisi_rjesenje(tezinska_matrica, matrica_feromonski_trag, alfa, beta)

            x_prim = posjeceni
            v_prim = f(x_prim, tezinska_matrica)

            if v_prim < v_zvijezda:
                v_zvijezda = v_prim
                x_zvijezda = x_prim
            omega.append(x_prim)
            putanje.append(v_prim)

        if v_zvijezda == v_min:
            reincijaliziraj += 1

        if v_zvijezda < v_min:
            v_min = v_zvijezda
            x_min = x_zvijezda

        #isparavanje feromonskog traga
        matrica_feromonski_trag = isparavanje_feromonskog_traga_MMAS(matrica_feromonski_trag, ro, v_min)

        #azuriraj feromonski trag
        random_broj = random.choice(range(0, 100))
        if random_broj % 2 == 0:
            najbolje_rjesenje = x_zvijezda
        else:
            minimalni = min(putanje)
            for h in range(len(omega)):
                if putanje[h] == minimalni:
                    najbolje_rjesenje = omega[h]
        matrica_feromonski_trag = azuriraj_feromonski_trag_MMAS(najbolje_rjesenje, tezinska_matrica, matrica_feromonski_trag, v_min, ro)

        if reincijaliziraj == M:
            matrica_feromonski_trag = reinicijaliziraj_MMAS(tezinska_matrica, matrica_feromonski_trag, v_min, ro)
            reincijaliziraj = 0

        if broj_iteracija == N:
            break
    return x_min, v_min


# -*- coding: utf-8 -*-
import click
import os
import signal

from gunicorn import util
from pyft import __version__, settings

@click.group()
def cli():
    pass

@cli.command('run', help='Run worker server.')
@click.option('--env', '-e', default='dev', help='Run as a daemon.')
def run(env):
    """ 웹서버를 실행한다.

    웹서버 환경은 dev, prod 로 구분되고 프로세스 개수는 환경에 따라 다르다.

    dev 모드는 무조건 1개로 고정하고 prod 모드는 settings.SERVER_PROCESS 값만큼 결정된다.

    """
    from pyft.app import App

    options = {
        'bind': '%s:%s' % (settings.SERVER_HOST, settings.SERVER_PORT),
        'timeout': settings.SERVER_TIMEOUT,
        'pidfile': settings.SERVER_PID_FILE,
        'loglevel': 'debug' if settings.DEBUG else 'error',
        'proc_name': settings.SERVER_PROCESS_NAME,
        'limit_request_lint': settings.LIMIT_REQUEST_LINE,
        'limit_request_fields': settings.LIMIT_REQUEST_FIELDS,
        'limit_request_field_size': settings.LIMIT_REQUEST_FIELD_SIZE,
    }

    if env == 'prod':
        util.daemonize(False)
        options['workers'] = int(settings.SERVER_PROCESS)

    App(options).run()

@cli.command('shutdown', help='Shutdown running servers.')
@click.option('--now', '-n', is_flag=True, help='Shutdown now.')
def shutdown(now):
    """ 웹서버를 종료한다."""
    try:
        if settings.SERVER_PID_FILE:
            pidfile = settings.SERVER_PID_FILE
            if os.path.exists(pidfile):
                with open(pidfile) as f:
                    pid = int(f.read().strip())
                os.kill(pid, signal.SIGKILL if now else signal.SIGTERM)
                click.echo(pid)
    except ProcessLookupError as e:
        click.echo(e)

@cli.command(help='Print version string.')
def version():
    click.echo(__version__)

def main():
    cli()


from sklearn.svm import LinearSVC
from sklearn.feature_selection import SelectFromModel
from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score
from sklearn import svm
from sklearn.feature_selection import VarianceThreshold
from sklearn.neighbors import KNeighborsClassifier
from sklearn.model_selection import cross_val_score
from sklearn.naive_bayes import BernoulliNB
from sklearn.neural_network import MLPClassifier
from sklearn.svm import LinearSVC
import numpy as np
import sys

#put the data in the correct format in order to use scikit
def setData( temp, max_coln ):
    data = np.zeros(shape=(1842, int(max_coln + 1)))

    for x in temp:
        row = int(x[0]) - 1
        col = int(x[1])
        data[row,col] = x[2]

    return data

#put the data in the correct format in order to use scikit
def setTestingData(temp, max_column):
    data = np.zeros(shape=(952, int(max_column + 1)))

    for x in temp:
        row = int(x[0]) - 1
        col = int(x[1])
        data[row,col] = x[2]

    return data

# extract features selected in feature reduction process and use the same for the test data
def reduce_test_data(indexes_to_keep, test_data):
    reduced_test_data = np.zeros(shape=(952, indexes_to_keep.size))
    for element_index in range(0, 952):
        feature_count = 0
        for idx in indexes_to_keep:
            reduced_test_data[element_index][feature_count] = test_data[element_index][idx]
            feature_count = feature_count + 1

    return reduced_test_data

def getDataSets():
    training_file = 'DataFiles/training.txt'
    training_labels_file = 'DataFiles/label_training.txt'
    testing_file = 'DataFiles/testing.txt'

    class_labels = np.genfromtxt(training_labels_file)
    temp_training_data = np.genfromtxt(training_file)
    training_set = setData(temp_training_data, temp_training_data.max())
    temp_test_data = np.genfromtxt(testing_file)
    test_data = setTestingData(temp_test_data, temp_test_data.max())

    return training_set, class_labels, test_data

def main():
    # get data sets in numpy array to run scikit algorithms on
    data_set, data_labels, test_data = getDataSets()

    # Reduce features based off feature variance.
    sel = VarianceThreshold(threshold=(.05))
    feature_reduced_data_set = sel.fit_transform(data_set)
    indexes_selected = sel.get_support(indices=True)
    reduced_test_data = reduce_test_data(indexes_selected, test_data)

    # train various classifiers
    neigh = KNeighborsClassifier(n_neighbors=50)
    k_neighbor_scores = cross_val_score(neigh, feature_reduced_data_set, data_labels, cv=5)
    ann = MLPClassifier(solver='lbfgs', alpha=1e-5, hidden_layer_sizes=(5, 2), random_state=1)
    ann_scores = cross_val_score(ann, feature_reduced_data_set, data_labels, cv=5)
    svm = LinearSVC()
    svm_scores = cross_val_score(svm, feature_reduced_data_set, data_labels, cv=5)

    # print accuracy Score of KNeighbor
    print("K_N Accuracy: %0.2f (+/- %0.2f)" % (k_neighbor_scores.mean(), k_neighbor_scores.std() * 2))
    print("ANN Accuracy: %0.2f (+/- %0.2f)" % (ann_scores.mean(), ann_scores.std() * 2))
    print("SVM Accuracy Score: %0.2f (+/- %0.2f)" % (svm_scores.mean(), svm_scores.std() * 2))

    # SVM was best algorithm, so label test data through classifer and write to file
    svm.fit(feature_reduced_data_set, data_labels)
    label_training_list = svm.predict(reduced_test_data)
    f = open('label_test.txt', 'w')
    for label in label_training_list:
        f.write(str(int(label)))
        f.write('\n')
    print('SVM Classifer used! Test labels written to label_test.txt')

if __name__ == '__main__':
    main()