# Copyright 2024 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#      http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

"""Utilities for unit tests."""
import datetime

# Matches the entire XML output. Captures all <testcase> tags except for the
# last closing </testcase> in a single group.
OUTPUT_STRING = r"""<\?xml version="1.0"\?>
<testsuites name="" tests="%(tests)d" failures="%(failures)d" errors="%(errors)d" time="%(run_time).3f" timestamp="%(start_time)s">
<testsuite name="%(suite_name)s" tests="%(tests)d" failures="%(failures)d" errors="%(errors)d" time="%(run_time).3f" timestamp="%(start_time)s">
(  <testcase [.\S\s]*)
  </testcase>
</testsuite>
</testsuites>
"""

# Matches a single <testcase> tag and its contents, without the closing
# </testcase>, which we use as a separator to split multiple <testcase> tags.
TESTCASE_STRING_WITH_PROPERTIES = r"""  <testcase name="%(test_name)s" status="%(status)s" result="%(result)s" time="%(run_time).3f" classname="%(class_name)s" timestamp="%(start_time)s">
    <properties>
%(properties)s
    </properties>%(message)s"""

# Matches a single <testcase> tag and its contents, without the closing
# </testcase>, which we use as a separator to split multiple <testcase> tags.
TESTCASE_STRING_WITH_ERRORS = r"""  <testcase name="%(test_name)s" status="%(status)s" result="%(result)s" time="%(run_time).3f" classname="%(class_name)s" timestamp="%(start_time)s">
  <error message="%(message)s" type="%(error_type)s"><\!\[CDATA\[%(error_msg)s\]\]></error>"""

# Matches a single <testcase> tag and its contents, without the closing
# </testcase>, which we use as a separator to split multiple <testcase> tags.
TESTCASE_STRING = r"""  <testcase name="%(test_name)s" status="%(status)s" result="%(result)s" time="%(run_time).3f" classname="%(class_name)s" timestamp="%(start_time)s">"""


def iso_timestamp(timestamp: float) -> str:
  """Makes timestamp in iso format for unit tests.

  Args:
    timestamp: Time value in float.

  Returns:
    Formatted time according to ISO.
  """
  return datetime.datetime.fromtimestamp(
      timestamp, tz=datetime.timezone.utc
  ).isoformat()


def make_summary(**kwargs) -> str:
  """Makes test summary produced by `test_reporter` for unit tests.

  Args:
    **kwargs: Fields written in test summary.

  Returns:
    Test summary.
  """
  dut = kwargs.get('dut', 'n/a')
  gha = kwargs.get('gha_version', 'n/a')
  test_date = kwargs.get('test_date', 'n/a')
  gms_core = kwargs.get('gms_core_version', 'n/a')
  duration = kwargs.get('duration', 0)
  hub = kwargs.get('hub_version', 'n/a')
  total_runs = kwargs.get('total_runs', 0)
  device = kwargs.get('device_firmware', 'n/a')
  total_successful_runs = kwargs.get('total_successful_runs', 0)
  success_rate = round(100.0 * float(total_successful_runs) / float(total_runs))
  rows: list[list[str]] = []
  rows.append(['Summary', '', 'Version Info', ''])
  rows.append(['DUT:', dut, 'GHA', gha])
  rows.append(['Test Time:', test_date, 'GMSCore', gms_core])
  rows.append(['Duration:', duration, 'Hub', hub])
  rows.append(['Number of runs:', str(total_runs), 'Device', device])
  rows.append([
      'Success Rate:',
      f'{success_rate}%({total_successful_runs}/{total_runs})',
  ])
  summary = []
  for row in rows:
    summary.append(''.join(element.ljust(25) for element in row))
    summary.append('\n')

  return ''.join(summary)


def make_test_case_result(
    total_runs: int,
    res_of_test_commission: list[str] | None,
    res_of_test_decommission: list[str] | None,
) -> str:
  """Makes test case result produced by `test_reporter` for unit tests.

  Args:
    total_runs: Total cycles for regression tests.
    res_of_test_commission: Elements in list should be `PASS`, `FAIL` or `N/A`,
      which indicates the test result for each test case `test_commission`.
    res_of_test_decommission: Elements in list should be `PASS`, `FAIL` or
      `N/A`, which indicates the test result for each test case
      `test_decommission`.

  Returns:
    Test case result.
  """
  test_case_result = ['Test Case/Test Run'.ljust(25)]
  for i in range(total_runs):
    test_case_result.append(f'#{i + 1}'.ljust(8))
  if res_of_test_commission:
    test_case_result.append('\n')
    test_case_result.append('Commission to GHA'.ljust(25))
    for res in res_of_test_commission:
      test_case_result.append(res.ljust(8))
  if res_of_test_decommission:
    test_case_result.append('\n')
    test_case_result.append('Removing from GHA'.ljust(25))
    for res in res_of_test_decommission:
      test_case_result.append(res.ljust(8))

  return ''.join(test_case_result)
