#!/usr/bin/python2
# Copyright 2015 The Chromium OS Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

from __future__ import print_function

import argparse
import os
import re

import chaos_capture_analyzer
import chaos_log_analyzer

class ChaosTestInfo(object):
    """ Class to gather the relevant test information from a folder. """

    MESSAGES_FILE_NAME = "messages"
    NET_LOG_FILE_NAME = "net.log"
    TEST_DEBUG_LOG_FILE_END = "DEBUG"
    SYSINFO_FOLDER_NAME_END = "sysinfo"
    TEST_DEBUG_FOLDER_NAME_END = "debug"

    def __init__(self, dir_name, file_names, failures_only):
        """
        Gathers all the relevant Chaos test results from a given folder.

        @param dir: Folder to check for test results.
        @param files: Files present in the folder found during os.walk.
        @param failures_only: Flag to indicate whether to analyze only
                              failure test attempts.

        """
        self._meta_info = None
        self._traces = []
        self._message_log = None
        self._net_log = None
        self._test_debug_log = None
        for file_name in file_names:
            if file_name.endswith('.trc'):
                basename = os.path.basename(file_name)
                if 'success' in basename and failures_only:
                    continue
                self._traces.append(os.path.join(dir_name, file_name))
        if self._traces:
            for root, dir_name, file_names in os.walk(dir_name):
                # Now get the log files from the sysinfo, debug folder
                if root.endswith(self.SYSINFO_FOLDER_NAME_END):
                    # There are multiple copies of |messages| file under
                    # sysinfo tree. We only want the one directly in sysinfo.
                    for file_name in file_names:
                        if file_name == self.MESSAGES_FILE_NAME:
                            self._message_log = os.path.join(root, file_name)
                    for root, dir_name, file_names in os.walk(root):
                        for file_name in file_names:
                            if file_name == self.NET_LOG_FILE_NAME:
                                self._net_log = os.path.join(root, file_name)
                if root.endswith(self.TEST_DEBUG_FOLDER_NAME_END):
                    for root, dir_name, file_names in os.walk(root):
                        for file_name in file_names:
                            if file_name.endswith(self.TEST_DEBUG_LOG_FILE_END):
                                self._test_debug_log = (
                                        os.path.join(root, file_name))
                                self._parse_meta_info(
                                        os.path.join(root, file_name))

    def _parse_meta_info(self, file):
        dut_mac_prefix ='\'DUT\': '
        ap_bssid_prefix ='\'AP Info\': '
        ap_ssid_prefix ='\'SSID\': '
        self._meta_info = {}
        with open(file) as infile:
            for line in infile.readlines():
                line = line.strip()
                if line.startswith(dut_mac_prefix):
                    dut_mac = line[len(dut_mac_prefix):].rstrip()
                    self._meta_info['dut_mac'] = (
                        dut_mac.replace('\'', '').replace(',', ''))
                if line.startswith(ap_ssid_prefix):
                    ap_ssid = line[len(ap_ssid_prefix):].rstrip()
                    self._meta_info['ap_ssid'] = (
                        ap_ssid.replace('\'', '').replace(',', ''))
                if line.startswith(ap_bssid_prefix):
                    debug_info = self._parse_debug_info(line)
                    if debug_info:
                        self._meta_info.update(debug_info)

    def _parse_debug_info(self, line):
        # Example output:
        #'AP Info': "{'2.4 GHz MAC Address': '84:1b:5e:e9:74:ee', \n
        #'5 GHz MAC Address': '84:1b:5e:e9:74:ed', \n
        #'Controller class': 'Netgear3400APConfigurator', \n
        #'Hostname': 'chromeos3-row2-rack2-host12', \n
        #'Router name': 'wndr 3700 v3'}",
        debug_info = line.replace('\'', '')
        address_label = 'Address: '
        bssids = []
        for part in debug_info.split(','):
            address_index = part.find(address_label)
            if address_index >= 0:
                address = part[(address_index+len(address_label)):]
                if address != 'N/A':
                    bssids.append(address)
        if not bssids:
            return None
        return { 'ap_bssids': bssids }

    def _is_meta_info_valid(self):
        return ((self._meta_info is not None) and
                ('dut_mac' in self._meta_info) and
                ('ap_ssid' in self._meta_info) and
                ('ap_bssids' in self._meta_info))

    @property
    def traces(self):
        """Returns the trace files path in test info."""
        return self._traces

    @property
    def message_log(self):
        """Returns the message log path in test info."""
        return self._message_log

    @property
    def net_log(self):
        """Returns the net log path in test info."""
        return self._net_log

    @property
    def test_debug_log(self):
        """Returns the test debug log path in test info."""
        return self._test_debug_log

    @property
    def bssids(self):
        """Returns the BSSID of the AP in test info."""
        return self._meta_info['ap_bssids']

    @property
    def ssid(self):
        """Returns the SSID of the AP in test info."""
        return self._meta_info['ap_ssid']

    @property
    def dut_mac(self):
        """Returns the MAC of the DUT in test info."""
        return self._meta_info['dut_mac']

    def is_valid(self, packet_capture_only):
        """
        Checks if the given folder contains a valid Chaos test results.

        @param packet_capture_only: Flag to indicate whether to analyze only
                                    packet captures.

        @return True if valid chaos results are found; False otherwise.

        """
        if packet_capture_only:
            return ((self._is_meta_info_valid()) and
                    (bool(self._traces)))
        else:
            return ((self._is_meta_info_valid()) and
                    (bool(self._traces)) and
                    (bool(self._message_log)) and
                    (bool(self._net_log)))


class ChaosLogger(object):
    """ Class to log the analysis to the given output file. """

    LOG_SECTION_DEMARKER = "--------------------------------------"

    def __init__(self, output):
        self._output = output

    def log_to_output_file(self, log_msg):
        """
        Logs the provided string to the output file.

        @param log_msg: String to print to the output file.

        """
        self._output.write(log_msg + "\n")

    def log_start_section(self, section_description):
        """
        Starts a new section in the output file with demarkers.

        @param log_msg: String to print in section description.

        """
        self.log_to_output_file(self.LOG_SECTION_DEMARKER)
        self.log_to_output_file(section_description)
        self.log_to_output_file(self.LOG_SECTION_DEMARKER)


class ChaosAnalyzer(object):
    """ Main Class to analyze the chaos test output from a given folder. """

    LOG_OUTPUT_FILE_NAME_FORMAT = "chaos_analyzer_try_%s.log"
    TRACE_FILE_ATTEMPT_NUM_RE = r'\d+'

    def _get_attempt_number_from_trace(self, trace):
        file_name = os.path.basename(trace)
        return re.search(self.TRACE_FILE_ATTEMPT_NUM_RE, file_name).group(0)

    def _get_all_test_infos(self, dir_name, failures_only, packet_capture_only):
        test_infos = []
        for root, dir, files in os.walk(dir_name):
            test_info = ChaosTestInfo(root, files, failures_only)
            if test_info.is_valid(packet_capture_only):
                test_infos.append(test_info)
        if not test_infos:
            print("Did not find any valid test info!")
        return test_infos

    def analyze(self, input_dir_name=None, output_dir_name=None,
                failures_only=False, packet_capture_only=False):
        """
        Starts the analysis of the Chaos test logs and packet capture.

        @param input_dir_name: Directory which contains the chaos test results.
        @param output_dir_name: Directory to which the chaos analysis is output.
        @param failures_only: Flag to indicate whether to analyze only
                              failure test attempts.
        @param packet_capture_only: Flag to indicate whether to analyze only
                                    packet captures.

        """
        for test_info in self._get_all_test_infos(input_dir_name, failures_only,
                                                  packet_capture_only):
            for trace in test_info.traces:
                attempt_num = self._get_attempt_number_from_trace(trace)
                trace_dir_name = os.path.dirname(trace)
                print("Analyzing attempt number: " + attempt_num + \
                      " from folder: " + os.path.abspath(trace_dir_name))
                # Store the analysis output in the respective log folder
                # itself unless there is an explicit output directory
                # specified in which case we prepend the |testname_| to the
                # output analysis file name.
                output_file_name = (
                        self.LOG_OUTPUT_FILE_NAME_FORMAT % (attempt_num))
                if not output_dir_name:
                    output_dir = trace_dir_name
                else:
                    output_dir = output_dir_name
                    output_file_name = "_".join([trace_dir_name,
                                                 output_file_name])
                output_file_path = (
                        os.path.join(output_dir, output_file_name))
                try:
                    with open(output_file_path, "w") as output_file:
                         logger = ChaosLogger(output_file)
                         protocol_analyzer = (
                                chaos_capture_analyzer.ChaosCaptureAnalyzer(
                                        test_info.bssids, test_info.ssid,
                                        test_info.dut_mac, logger))
                         protocol_analyzer.analyze(trace)
                         if not packet_capture_only:
                             with open(test_info.message_log, "r") as message_log, \
                                  open(test_info.net_log, "r") as net_log:
                                  log_analyzer = (
                                         chaos_log_analyzer.ChaosLogAnalyzer(
                                                message_log, net_log, logger))
                                  log_analyzer.analyze(attempt_num)
                except IOError as e:
                    print('Operation failed: %s!' % e.strerror)


def main():
    # By default the script parses all the logs places under the current
    # directory and places the analyzed output for each set of logs in their own
    # respective directories.
    parser = argparse.ArgumentParser(description='Analyze Chaos logs.')
    parser.add_argument('-f', '--failures-only', action='store_true',
                        help='analyze only failure logs.')
    parser.add_argument('-p', '--packet-capture-only', action='store_true',
                        help='analyze only packet captures.')
    parser.add_argument('-i', '--input-dir', action='store', default='.',
                        help='process the logs from directory.')
    parser.add_argument('-o', '--output-dir', action='store',
                        help='output the analysis to directory.')
    args = parser.parse_args()
    chaos_analyzer = ChaosAnalyzer()
    chaos_analyzer.analyze(input_dir_name=args.input_dir,
                           output_dir_name=args.output_dir,
                           failures_only=args.failures_only,
                           packet_capture_only=args.packet_capture_only)

if __name__ == "__main__":
    main()

