# -*- coding: utf-8 -*-
#
# Copyright (c) 2014 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.

"""A simple battery test.

A simple battery test that charges, discharges, and charges a battery on a
DUT.  The goal of this factory test is to do a quick basic verification of
battery function (typically less than 30 seconds).
"""

from __future__ import print_function

import logging
import time
import unittest

import factory_common   # pylint: disable=W0611
from cros.factory import system
from cros.factory.system import board
from cros.factory.test import factory
from cros.factory.test import test_ui
from cros.factory.test import ui_templates
from cros.factory.test import utils
from cros.factory.test.args import Arg
from cros.factory.utils import sync_utils
from cros.factory.utils import time_utils


_TEST_TITLE = test_ui.MakeLabel('Simple Battery Test', u'简单电池测试')
_UNPLUG_AC = test_ui.MakeLabel('Unplug AC to proceed', u'拔除 AC 电源')
_PLUG_AC = test_ui.MakeLabel('Plug AC to proceed', u'插上 AC 电源')
_TESTING_CHARGE = test_ui.MakeLabel('Testing battery charge...',
                                    u'测试电池充电中...')
_TESTING_DISCHARGE = test_ui.MakeLabel('Testing battery discharge...',
                                       u'测试电池放电中...')
_CSS = 'body { font-size: 2em; }'


class SimpleBatteryTest(unittest.TestCase):
  """A simple battery test."""
  ARGS = [
      Arg('charge_duration_secs', type=(int, float), default=5,
          help='the duration in seconds to charge the battery'),
      Arg('discharge_duration_secs', type=(int, float), default=5,
          help='the duration in seconds to discharge the battery'),
      Arg('min_charge_current_mA', type=(int, float), default=None,
          optional=True,
          help=('the minimum charge current in mA that the battery needs to '
                'reach during charge test')),
      Arg('min_discharge_current_mA', type=(int, float), default=-2000,
          help=('the minimum discharge current in mA that the battery needs to '
                'reach during discharge test')),
      Arg('current_sampling_period_secs', type=(int, float), default=0.5,
          help=('the period in seconds to sample charge/discharge current '
                'during test')),
      Arg('max_cycle_count', type=int, default=1,
          help=('the maximum cycle count beyond which the battery is considered'
                'used')),
  ]

  def setUp(self):
    self.VerifyArgs()
    self._ui = test_ui.UI(css=_CSS)
    self._template = ui_templates.OneSection(self._ui)
    self._template.SetTitle(_TEST_TITLE)
    self._board = system.GetBoard(self.dut)

  def VerifyArgs(self):
    if self.args.min_charge_current_mA:
      if not self.args.min_charge_current_mA > 0:
        raise factory.FactoryTestFailure(
            'min_charge_current_mA must be greater than zero')
    if self.args.min_discharge_current_mA:
      if not self.args.min_discharge_current_mA < 0:
        raise factory.FactoryTestFailure(
            'min_discharge_current_mA must be less than zero')

  def SampleBatteryCurrent(self, duration_secs):
    """Samples battery current for a given duration.

    Args:
      duration_secs: The duration in seconds to sample battery current.

    Returns:
      A list of sampled battery current.
    """
    sampled_current = []
    end_time = time_utils.MonotonicTime() + duration_secs
    while time_utils.MonotonicTime() < end_time:
      sampled_current.append(self._board.GetBatteryCurrent())
      time.sleep(self.args.current_sampling_period_secs)
    logging.info('Sampled battery current: %s', str(sampled_current))
    return sampled_current

  def TestCharge(self, duration_secs):
    """Tests battery charging for a given duration.

    Args:
      duration_secs: The duration in seconds to test charging the battery.

    Raises:
      FactoryTestFailure if the sampled battery charge current does not pass
      the given threshold in dargs.
    """
    self._template.SetState(_PLUG_AC)
    sync_utils.WaitFor(self._board.power.CheckACPresent, timeout_secs=10)
    self._template.SetState(_TESTING_CHARGE)
    self._board.SetChargeState(board.Board.ChargeState.CHARGE)
    sampled_current = self.SampleBatteryCurrent(duration_secs)
    if self.args.min_charge_current_mA:
      if not any(
          [c > self.args.min_charge_current_mA for c in sampled_current]):
        raise factory.FactoryTestFailure(
            'Battery charge current did not reach defined threshold %f mA' %
            self.args.min_charge_current_mA)
    else:
      if not any([c > 0 for c in sampled_current]):
        raise factory.FactoryTestFailure(
            'Battery was not charging during charge test')

  def TestDischarge(self, duration_secs):
    """Tests battery discharging for a given duration.

    The test runs under high system load to maximize battery discharge current.

    Args:
      duration_secs: The duration in seconds to test discharging the battery.

    Raises:
      FactoryTestFailure if the sampled battery discharge current does not pass
      the given threshold in dargs.
    """
    self._template.SetState(_UNPLUG_AC)
    sync_utils.WaitFor(lambda: not self._board.power.CheckACPresent(),
                       timeout_secs=10)
    self._template.SetState(_TESTING_DISCHARGE)
    # Discharge under high system load.
    with utils.LoadManager(duration_secs):
      sampled_current = self.SampleBatteryCurrent(duration_secs)
    if self.args.min_discharge_current_mA:
      if not any(
          [c < self.args.min_discharge_current_mA for c in sampled_current]):
        raise factory.FactoryTestFailure(
            'Battery discharge current did not reach defined threshold %f mA' %
            self.args.min_discharge_current_mA)
    else:
      if not any([c < 0 for c in sampled_current]):
        raise factory.FactoryTestFailure(
            'Battery was not discharging during charge test')

  def runTest(self):
    if not self._board.power.CheckBatteryPresent():
      raise factory.FactoryTestFailure(
          'Cannot locate battery sysfs path. Missing battery?')
    cycle_count = self._board.power.GetBatteryAttribute('cycle_count').strip()
    if int(cycle_count) > self.args.max_cycle_count:
      raise factory.FactoryTestFailure(
          'Battery cycle count %s exceeds max %d' %
          (cycle_count, self.args.max_cycle_count))
    self.TestCharge(self.args.charge_duration_secs)
    self.TestDischarge(self.args.discharge_duration_secs)
    self.TestCharge(self.args.charge_duration_secs)
