#!/usr/bin/python
# Copyright 2018 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.

"""The testplan module.

The testplan module will go through the CSV file (the format of which is
defined below) and put them to a TestPlan object, which acts like a read-only
list of the TestCase.

The format of the CSV file.
The first column is '@config' is for the config.
The format: @config, key, value

The first column is '@title' is for the header containing the names of arguments
and result. There is another '@result' between the arguments and the results.
The format:
  @title, arg_key1, arg_key2, ..., @result, result_key1, result_key2, ...

Other rows contain a test case. Before these row there should be a valid header.
The format:
  , arg_value1, arg_value2, ...,, result_value1, result_value2, ...

We use the number sign(#) as the comment character.
If the first column starts from #, we ignore the rest of the line.
"""

import csv
import itertools
import logging

import graphyte_common  # pylint: disable=unused-import
from graphyte.data_parser import ListChecker
from graphyte.data_parser import TupleChecker
from graphyte.data_parser import Parse
from graphyte.default_setting import logger
from graphyte.utils.graphyte_utils import IsInBound
from graphyte.utils.graphyte_utils import SearchConfig


CONFIG_MARKER = '@config'
TITLE_MARKER = '@title'
RESULT_MARKER = '@result'


HEADER_CHECKER = {
    'order_by': ListChecker(['component_name', 'rf_type', 'test_type',
                             'center_freq', 'power_level'])}
SUPPORTED_RF_TYPES = ['WLAN', 'BLUETOOTH', '802_15_4']
SUPPORTED_TEST_TYPES = ['TX', 'RX']


class TestPlan(object):
  """Generates the test plan from CSV file.

  The class parses the CSV file and generates a list of test cases.

  Usage:
    test_plan = TestPlan(config_file)
    if not test_plan:
      print 'Error: Failed to load the config file.'
    for test_case in test_plan:
      print 'test_case: %s' % str(test_case)
  """

  def __init__(self, config_file=None, search_dirs=None):
    self.test_cases = []
    self.test_config = {}
    if config_file:
      self.LoadConfigFile(config_file, search_dirs)

  def __len__(self):
    """Returns the count of the test cases.

    we implement __len__ and __getitem__ to make TestPlan behave like a
    read-only list.
    """
    return len(self.test_cases)

  def __getitem__(self, index):
    return self.test_cases[index]

  def LoadConfigFile(self, config_file, search_dirs=None):
    try:
      self.ParseCSVFile(config_file, search_dirs)
    except ValueError:
      logger.exception('Parsing csv file %s error.', config_file)
      self.test_cases = []

    order_by = self.test_config.get('order_by', None)
    if order_by is not None:
      cmp_key = lambda test_case: test_case.ResolveAttr(order_by)
      self.test_cases.sort(key=cmp_key)

  def ParseCSVFile(self, config_file, search_dirs=None):
    def _LogErrorAndRaise(row_idx, msg):
      msg = 'Row %d: %s' % (row_idx, msg)
      logger.error(msg)
      raise ValueError(msg)

    logger.info('Loading test config file: %s', config_file)
    with open(SearchConfig(config_file, search_dirs)) as csv_file:
      reader = csv.reader(csv_file)
      header = None
      split_idx = None
      for row_idx, row in enumerate(reader, start=1):
        row = StripRow(row)
        if len(row) == 0:
          continue

        if row[0].startswith('#'):
          continue
        # General config starts with '@config'
        elif row[0] == CONFIG_MARKER:
          if len(row) != 3:
            _LogErrorAndRaise(row_idx,
                              'The format of config row should be: '
                              '@config, <key>, <value>')
          key, value = row[1], row[2]
          data = Parse(value, HEADER_CHECKER.get(key))
          self.test_config[key] = data
          logger.debug('test_config: %s', self.test_config)
        # Header starts with '@title', arguments and results is splitted by
        # '@result'
        elif row[0] == TITLE_MARKER:
          header = row[1:]
          try:
            split_idx = header.index(RESULT_MARKER)
          except ValueError:
            _LogErrorAndRaise(row_idx, '%s is missing' % RESULT_MARKER)
          arg_header, result_header = header[:split_idx], header[split_idx+1:]
        # Each line represents a group of test cases
        else:
          if header is None:
            _LogErrorAndRaise(
                row_idx, 'There should be valid title before content.')
          value = row[1:]
          if len(value) != len(header):
            _LogErrorAndRaise(
                row_idx, 'The length of data is different from the header.')
          try:
            arg_data = [Parse(data) for data in value[:split_idx]]
            arg_table = dict(zip(arg_header, arg_data))
            result_data = [Parse(data) for data in value[split_idx+1:]]
            result_limit = dict(zip(result_header, result_data))
          except ValueError as ex:
            _LogErrorAndRaise(row_idx, str(ex))
          # Generate the test cases with all combination of arguments
          for key in arg_table:
            if not isinstance(arg_table[key], list):
              arg_table[key] = [arg_table[key]]
          arg_keys = arg_table.keys()
          logger.debug('arg_keys: %s', arg_keys)
          for arg_values in itertools.product(*arg_table.values()):
            logger.debug('arg_values: %s', arg_values)
            args = dict(zip(arg_keys, arg_values))
            try:
              self.test_cases.extend(CreateTestCase(args, result_limit))
            except ValueError as ex:
              _LogErrorAndRaise(row_idx, str(ex))


def CreateTestCase(args, result_limit):
  """Creates the test case according to the RF type.

  Since the verification and the generation of the test case for each RF type
  are slightly different, we use the simple factory pattern to create the test
  case.

  Args:
    args: the arguments of the test case.
    result_limit: the result limit of the test case.

  Return:
    a list of the test case.
  """
  factory_map = {
      'WLAN': WLANTestCaseFactory(),
      'BLUETOOTH': BluetoothTestCaseFactory(),
      '802_15_4': ZigbeeTestCaseFactory()}
  try:
    factory = factory_map[args['rf_type']]
  except KeyError:
    raise ValueError('Invalid args %s: unsupported RF type.' % args)
  return factory.Create(args, result_limit)


class TestCaseFactory(object):
  """The abstract class for generating a test case of the certain RF type.

  The class is mainly for verifying the arguments and the result limit are
  valid, and then creating the test case.
  """

  def Create(self, args, result_limit):
    self._VerifyArgAndResult(args, result_limit)
    return self._Create(args, result_limit)

  def _VerifyArgAndResult(self, args, result_limit):
    """Verifies the test case is valid or not.

    1. Check the RF type is correct.
    2. Check all required arguments exist and are valid.
    3. Check there is at least one result and all results are valid.

    Raises:
      KeyError if the required arguments are missing.
      ValueError if the test case is not valid.
    """
    raise NotImplementedError

  def _Create(self, args, result_limit):
    name = self._GenerateCanonicalName(args)
    return [TestCase(name, args, result_limit)]

  @property
  def canonical_arg_order(self):
    """The argument order of the canonical name.

    Returns:
      a list of the argument name.
    """
    raise NotImplementedError

  def _GenerateCanonicalName(self, args):
    arg_values = [args[key] for key in self.canonical_arg_order if key in args]
    return ' '.join(map(str, arg_values))

  @staticmethod
  def VerifyArguments(checker_dict, args):
    """Verifies all arguments are valid.

    If the keys of args are not the same as checker_dict, or there is any value
    is not valid, then raise the ValueError exception.

    Args:
      checker_dict: a dict which keys are the valid args and values are
                    corresponding data checkers. For example:
        {
          'rf_type': ListChecker(['WLAN', 'BLUETOOTH', '802_15_4']),
          'test_type': ListChecker(['TX', 'RX'])
        }
      args: the arguments of the test case.

    Raises:
      ValueError if args does not pass the verification.
    """
    if set(args.keys()) != set(checker_dict.keys()):
      missing_keys = list(set(checker_dict.keys()) - set(args.keys()))
      unknown_keys = list(set(args.keys()) - set(checker_dict.keys()))
      err_str = 'The keys of arguments are not valid.'
      if missing_keys:
        err_str += ' The keys %s are missing.' % (missing_keys)
      if unknown_keys:
        err_str += ' The keys %s are unknown.' % (unknown_keys)
      raise ValueError(err_str)
    for key, value in args.items():
      if not checker_dict[key].CheckData(value):
        raise ValueError('"%s" is not valid for %s.' % (value, key))

  @staticmethod
  def _VerifyResults(result_list, result_limit):
    """Verifies all results are valid.

    If there is key of result_limit not in result_list, or the value is not
    valid, then raise the ValueError exception.

    Args:
      result_list: a list of all valid result keys.
      result_limit: the result limit of the test case.

    Raises:
      ValueError if data is not passed the verification.
    """
    result_checker = TupleChecker(([None, int, float],  # lower bound
                                   [None, int, float]))  # upper bound

    if not result_limit:
      raise ValueError('There is no result.')
    unknown_keys = set(result_limit.keys()) - set(result_list)
    if unknown_keys:
      raise ValueError('The keys %s are unknown.' % list(unknown_keys))
    for key, value in result_limit.items():
      if not result_checker.CheckData(value):
        raise ValueError('"%s" is not valid for %s.' % (value, key))


class WLANTestCaseFactory(TestCaseFactory):
  RF_TYPE = 'WLAN'

  REQUIRED_ARG_CHECKER = {
      'rf_type':        ListChecker([RF_TYPE]),
      'component_name': ListChecker([str]),
      'test_type':      ListChecker(SUPPORTED_TEST_TYPES),
      'center_freq':    ListChecker([lambda freq: 2400 < freq < 6000]),
      'power_level':    ListChecker([int, float, 'auto']),
      'standard':       ListChecker(['A', 'AC', 'B', 'G', 'N']),
      'bandwidth':      ListChecker([20, 40, 80, 160]),
      'data_rate':      ListChecker([1, 2, 5.5, 11,
                                     6, 9, 12, 18, 24, 36, 48, 54] +
                                    ['MCS' + str(i) for i in range(32)]),
      'chain_mask':     ListChecker(range(1, 16)),  # 4x4 MIMO supported
      'nss':            ListChecker([None, 1, 2, 3, 4]),
      'long_preamble':  ListChecker([0, 1])}
  RX_ARG_CHECKER = {
      'rx_num_packets': ListChecker([int])}
  TX_RESULTS = ['evm', 'avg_power', 'freq_error', 'lo_leakage', 'mask_margin',
                'spectral_flatness', 'obw', 'phase_noise']
  RX_RESULTS = ['rx_per']

  def _VerifyArgAndResult(self, args, result_limit):
    # TODO(akahuang): standard to data_rate mapping
    # Check the RF type is valid.
    if self.RF_TYPE != args['rf_type']:
      raise ValueError('%s is not a valid RF type.' % args['rf_type'])
    # Check all required arguments are valid.
    arg_checker = self.REQUIRED_ARG_CHECKER.copy()
    if args['test_type'] == 'RX':
      arg_checker.update(self.RX_ARG_CHECKER)
    TestCaseFactory.VerifyArguments(arg_checker, args)
    # Check there is result and all results are valid.
    if args['test_type'] == 'TX':
      result_list = self.TX_RESULTS
    else:
      result_list = self.RX_RESULTS
    TestCaseFactory._VerifyResults(result_list, result_limit)

  @property
  def canonical_arg_order(self):
    return [
        'rf_type', 'component_name', 'test_type', 'center_freq',
        'standard', 'data_rate', 'bandwidth', 'chain_mask']

  def _GenerateCanonicalName(self, args):
    args = args.copy()  # do not change the original argument.
    args['bandwidth'] = 'BW-' + str(args['bandwidth'])
    chain_list = ChainMaskToList(args['chain_mask'])
    args['chain_mask'] = 'ANTENNA-' + ''.join(map(str, chain_list))
    return super(WLANTestCaseFactory, self)._GenerateCanonicalName(args)


class BluetoothTestCaseFactory(TestCaseFactory):
  RF_TYPE = 'BLUETOOTH'
  REQUIRED_ARG_CHECKER = {
      'rf_type':        ListChecker([RF_TYPE]),
      'component_name': ListChecker([str]),
      'test_type':      ListChecker(SUPPORTED_TEST_TYPES),
      'center_freq':    ListChecker([lambda freq: 2400 < freq < 2500]),
      'power_level':    ListChecker([int, float, 'auto']),
      'packet_type':    ListChecker(['1DH1', '1DH3', '1DH5', '2DH1', '2DH3',
                                     '2DH5', '3DH1', '3DH3', '3DH5', 'LE'])}
  LE_RX_ARG_CHECKER = {
      'rx_num_packets': ListChecker([int])}
  BT_RX_ARG_CHECKER = {
      'rx_num_bits': ListChecker([int])}
  COMMON_RESULTS = [
      'avg_power', 'acp_5', 'acp_4', 'acp_3', 'acp_2',
      'acp_1', 'acp0', 'acp1', 'acp2', 'acp3', 'acp4', 'acp5']
  FORMAT_RESULT_CHECKER = {
      'BDR': ['bandwidth_20db', 'freq_deviation', 'freq_drift', 'delta_f1_avg',
              'delta_f2_avg', 'delta_f2_max', 'delta_f2_f1_avg_ratio'],
      'EDR': ['freq_deviation', 'edr_evm_avg', 'edr_evm_peak',
              'edr_extreme_omega_0', 'edr_extreme_omega_i0', 'edr_omega_i',
              'edr_power_diff', 'edr_prob_evm_99_pass'],
      'LE': ['freq_offset', 'delta_f1_avg', 'delta_f2_avg',
             'delta_f2_max', 'delta_f0_fn_max', 'delta_f1_f0',
             'delta_fn_fn5_max', 'delta_f2_f1_avg_ratio']}
  LE_RX_RESULTS = ['rx_per']
  BT_RX_RESULTS = ['rx_ber']

  # For a Bluetooth test case, each result needs different bit pattern.
  # This dict records the relation between results and bit patterns.
  # NOTE1: This dict only for BDR and LE. EDR only uses PRBS9 pattern.
  # That is, EDR freq_deviation still uses PRBS9.
  # NOTE2: delta_f2_f1_avg_ratio is the ratio of delta_f2_avg and delta_f1_avg,
  # so it needs 'F0' and 'AA' patterns.
  BIT_PATTERN_RESULTS = {
      'PRBS9': ['avg_power', 'bandwidth_20db', 'acp_5', 'acp_4', 'acp_3',
                'acp_2', 'acp_1', 'acp0', 'acp1', 'acp2', 'acp3', 'acp4',
                'acp5', 'freq_offset', 'rx_ber', 'rx_per'],
      'F0': ['freq_deviation', 'delta_f1_avg', 'delta_f2_f1_avg_ratio'],
      'AA': ['freq_drift', 'delta_f2_avg', 'delta_f2_max', 'delta_f1_f0',
             'delta_f2_f1_avg_ratio', 'delta_f0_fn_max', 'delta_fn_fn5_max']}

  # The maximum number of bytes for each BDR and EDR packet type.
  # In Rx test, the instrument should transmit the largest packet.
  # Ref: Bluetooth Core Specification 4.0 Table 6.9: ACL packets.
  MAX_PACKET_LENGTH = {
      '1DH1': 27,
      '1DH3': 183,
      '1DH5': 339,
      '2DH1': 54,
      '2DH3': 367,
      '2DH5': 679,
      '3DH1': 83,
      '3DH3': 552,
      '3DH5': 1021}

  def _DetermineFormat(self, packet_type):
    """Determines the bluetooth format of the packet type.

    Args:
      packet_type: the Bluetooth packet type.

    Returns:
      one of 'LE', 'BDR', or 'EDR'.
    """
    if packet_type == 'LE':
      return 'LE'
    # The Bluetooth packet types are in the format: nXYm
    # n indicates modulation type. 1 is 1Mbps (basic data rate).
    # 2 is 2Mbps, 3 is 3Mbps modulation (enhanced data rate).
    # Hence the packet type starts from '2' or '3' is EDR, otherwise is BDR.
    if packet_type[0] in ['2', '3']:
      return 'EDR'
    return 'BDR'

  def _VerifyArgAndResult(self, args, result_limit):
    # Check the RF type is valid.
    if self.RF_TYPE != args['rf_type']:
      raise ValueError('%s is not a valid RF type.' % args['rf_type'])
    # Check all required arguments are valid.
    arg_checker = self.REQUIRED_ARG_CHECKER.copy()
    if args['test_type'] == 'RX':
      if args['packet_type'] == 'LE':
        arg_checker.update(self.LE_RX_ARG_CHECKER)
      else:
        arg_checker.update(self.BT_RX_ARG_CHECKER)
    TestCaseFactory.VerifyArguments(arg_checker, args)
    # Check there is result and all results are valid.
    if args['test_type'] == 'TX':
      result_list = self.COMMON_RESULTS[:]
      packet_format = self._DetermineFormat(args['packet_type'])
      result_list += self.FORMAT_RESULT_CHECKER[packet_format]
    elif args['packet_type'] == 'LE':
      result_list = self.LE_RX_RESULTS
    else:
      result_list = self.BT_RX_RESULTS
    TestCaseFactory._VerifyResults(result_list, result_limit)

  def _Create(self, args, result_limit):
    """Creates the bluetooth test case.

    For BDR and LE, the bit pattern of the packet are different from results.
    We add the 'bit_pattern' argument and split into different test cases.
    There is only 'PRBS9' bit pattern for EDR.
    """
    name = self._GenerateCanonicalName(args)
    packet_format = self._DetermineFormat(args['packet_type'])
    # Convert rx_num_bits to rx_num_packets. Add 10% packets for some loss.
    if args['test_type'] == 'RX' and packet_format != 'LE':
      args['rx_num_packets'] = int(1.1 * args['rx_num_bits'] / 8 /
                                   self.MAX_PACKET_LENGTH[args['packet_type']])
    if packet_format == 'EDR':
      args['bit_pattern'] = 'PRBS9'
      return [TestCase(name, args, result_limit)]
    # Split the test case by the bit pattern.
    ret = []
    for bit_pattern, result_list in self.BIT_PATTERN_RESULTS.items():
      filtered_result = dict(
          (k, v) for k, v in result_limit.items() if k in result_list)
      if filtered_result:
        copy_args = args.copy()
        copy_args['bit_pattern'] = bit_pattern
        ret.append(TestCase(name, copy_args, filtered_result))
    return ret

  @property
  def canonical_arg_order(self):
    return ['rf_type', 'component_name', 'test_type', 'center_freq',
            'packet_type']


class ZigbeeTestCaseFactory(TestCaseFactory):
  RF_TYPE = '802_15_4'
  REQUIRED_ARG_CHECKER = {
      'rf_type':        ListChecker([RF_TYPE]),
      'component_name': ListChecker([str]),
      'test_type':      ListChecker(SUPPORTED_TEST_TYPES),
      'center_freq':    ListChecker([lambda freq: 2400 < freq < 6000]),
      'power_level':    ListChecker([int, float, 'auto'])}
  RX_ARG_CHECKER = {
      'rx_num_packets': ListChecker([int])}

  TX_RESULTS = ['avg_power', 'evm_all', 'evm_offset', 'freq_error']
  RX_RESULTS = ['rx_per']

  def _VerifyArgAndResult(self, args, result_limit):
    # Check the RF type is valid.
    if self.RF_TYPE != args['rf_type']:
      raise ValueError('%s is not a valid RF type.' % args['rf_type'])
    # Check all required arguments are valid.
    arg_checker = self.REQUIRED_ARG_CHECKER.copy()
    if args['test_type'] == 'RX':
      arg_checker.update(self.RX_ARG_CHECKER)
    TestCaseFactory.VerifyArguments(arg_checker, args)
    # Check there is result and all results are valid.
    if args['test_type'] == 'TX':
      result_list = self.TX_RESULTS
    else:
      result_list = self.RX_RESULTS
    TestCaseFactory._VerifyResults(result_list, result_limit)

  @property
  def canonical_arg_order(self):
    return ['rf_type', 'component_name', 'test_type', 'center_freq']


class TestCase(object):
  """The test case. It contains the arguments of a RF test."""

  def __init__(self, name, args, result_limit):
    """Initializes the test case.

    Arg:
      name: A string that should contain important arguments information.
      args: A dict of the test arguments. The key 'rf_type', 'test_type' and
          'component_name' are essential.
          Example:
          {
            'component_name': 'WLAN_2G',
            'rf_type': 'WLAN',
            'test_type': 'TX',
            'center_freq': 2412
          }
      result_limit: A dict of the test result. The values are a tuple of lower
          bound and upper bound.
          Example:
          {
            'evm': (None, -25),
            'avg_power': (16, 20)
          }
    """
    self.rf_type = args['rf_type']
    self.test_type = args['test_type']
    self.args = args
    self.result_limit = result_limit
    self.name = name

  def __str__(self):
    return self.name

  def ResolveAttr(self, arg_keys):
    """Returns the value in args. It's used for sorting the test cases."""
    return tuple([self.args.get(arg_key) for arg_key in arg_keys])

  def CheckTestPasses(self, result):
    """Checks the result meets the result limit of the test case or not.

    The method verifies that each item in the `result_limit` is included in the
    result dict, and verifies that the result value meets the limit.

    Args:
      result: A dict in which keys should contain all the keys of
          `self.result_limit`, and the values are the result values.

    Returns:
      True if every result value meets the result limit.
    """
    is_pass = True
    for key in self.result_limit.keys():
      # Check there are all the required items in the result.
      if key not in result:
        logger.error('The result of %s is missing.', key)
        is_pass = False
      # Check the result value meets the result limit.
      elif not IsInBound(result[key], self.result_limit[key]):
        logger.info('The test in result %s failed. %s not in %s',
                    key, result[key], self.result_limit[key])
        is_pass = False
    return is_pass

  def ToDict(self):
    """Returns a dictionary containing all arguments of the class.

    It is for expanding the arguments of the function. For example:

      def foo(component_name, **kwargs):
        pass
      foo(**test_case.ToDict())
    """
    ret = self.args.copy()
    ret['result_limit'] = self.result_limit.copy()
    ret['name'] = self.name
    return ret

  def Copy(self):
    return TestCase(self.name, self.args.copy(), self.result_limit.copy())


def ChainMaskToList(chain_mask):
  """Converts the chain mask to the list of active antenna, starts from 0.

  The chain mask is the indicator of the activated antenna in binary
  representation. LSB means the first antenna and we called it antenna #0. For
  example:
    1 (b0001) means the first antenna is activated.
    2 (b0010) means the second antenna is activated.
    3 (b0011) means the first and the second antenna are activated.
  If the chain_mask is None, it means there is only 1 antenna.

  Args:
    chain_mask: None or integer.

  Returns:
    A list of integer which contains the activated antenna indices.
  """
  if chain_mask is None:
    return [0]
  ret = []
  antenna_idx = 0
  while chain_mask > 0:
    if chain_mask & 1:
      ret.append(antenna_idx)
    chain_mask >>= 1
    antenna_idx += 1
  return ret


def StripRow(row):
  """Strips every item in the row, and remove the right side of empty item."""
  row = [item.strip() for item in row]
  while len(row) > 0 and len(row[-1]) == 0:
    row.pop()
  return row
