# Copyright 2017 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.

import os
import csv
import json
import time
import urllib
import urllib2
import logging
import httplib

import enterprise_longevity_helper
from autotest_lib.client.common_lib import error
from autotest_lib.client.common_lib.cros import tpm_utils
from autotest_lib.server import autotest
from autotest_lib.server import test
from autotest_lib.server.cros.multimedia import remote_facade_factory


STABILIZATION_DURATION = 60
MEASUREMENT_DURATION_SECONDS = 10
TMP_DIRECTORY = '/tmp/'
PERF_FILE_NAME_PREFIX = 'perf'
VERSION_PATTERN = r'^(\d+)\.(\d+)\.(\d+)$'
DASHBOARD_UPLOAD_URL = 'https://chromeperf.appspot.com/add_point'
EXPECTED_PARAMS = ['perf_capture_iterations',  'perf_capture_duration',
                   'sample_interval', 'metric_interval', 'test_type',
                   'kiosk_app_attributes']


class PerfUploadingError(Exception):
    """Exception raised in perf_uploader."""
    pass


class enterprise_LongevityTrackerServer(test.test):
    """
    Run Longevity Test: Collect performance data over long duration.

    Run enterprise_KioskEnrollment and clear the TPM as necessary. After
    enterprise enrollment is successful, collect and log cpu, memory, and
    temperature data from the device under test.

    """
    version = 1


    def initialize(self):
        self.temp_dir = os.path.split(self.tmpdir)[0]


    #TODO(krishnargv@): Add a method to retrieve the version of the
    #                   Kiosk app from its manifest.
    def _initialize_test_variables(self):
        """Initialize test variables that will be uploaded to the dashboard."""
        self.board_name = self.system_facade.get_current_board()
        self.chromeos_version = self.system_facade.get_chromeos_release_version()
        epoch_minutes = str(int(time.time() / 60))
        self.point_id = enterprise_longevity_helper.get_point_id(
                self.chromeos_version, epoch_minutes, VERSION_PATTERN)
        self.test_suite_name = self.tagged_testname
        self.perf_capture_duration = self.perf_params['perf_capture_duration']
        self.sample_interval = self.perf_params['sample_interval']
        self.metric_interval = self.perf_params['metric_interval']
        self.perf_results = {'cpu': '0', 'mem': '0', 'temp': '0'}


    def elapsed_time(self, mark_time):
        """
        Get time elapsed since |mark_time|.

        @param mark_time: point in time from which elapsed time is measured.

        @returns time elapsed since the marked time.

        """
        return time.time() - mark_time


    #TODO(krishnargv):  Replace _format_data_for_upload with a call to the
    #                   _format_for_upload method of the perf_uploader.py
    def _format_data_for_upload(self, chart_data):
        """
        Collect chart data into an uploadable data JSON object.

        @param chart_data: performance results formatted as chart data.

        """
        perf_values = {
            'format_version': '1.0',
            'benchmark_name': self.test_suite_name,
            'charts': chart_data,
        }
        #TODO(krishnargv): Add a method to capture the chrome_version.
        dash_entry = {
            'master': 'ChromeOS_Enterprise',
            'bot': 'cros-%s' % self.board_name,
            'point_id': self.point_id,
            'versions': {
                'cros_version': self.chromeos_version,

            },
            'supplemental': {
                'default_rev': 'r_cros_version',
                'kiosk_app_name': 'a_' + self.kiosk_app_name,

            },
            'chart_data': perf_values
        }
        return {'data': json.dumps(dash_entry)}


    #TODO(krishnargv):  Replace _send_to_dashboard with a call to the
    #                   _send_to_dashboard method of the perf_uploader.py
    def _send_to_dashboard(self, data_obj):
        """
        Send formatted perf data to the perf dashboard.

        @param data_obj: data object as returned by _format_data_for_upload().

        @raises PerfUploadingError if an exception was raised when uploading.

        """
        logging.debug('Data_obj to be uploaded: %s', data_obj)
        encoded = urllib.urlencode(data_obj)
        req = urllib2.Request(DASHBOARD_UPLOAD_URL, encoded)
        try:
            urllib2.urlopen(req)
        except urllib2.HTTPError as e:
            raise PerfUploadingError('HTTPError: %d %s for JSON %s\n' %
                                     (e.code, e.msg, data_obj['data']))
        except urllib2.URLError as e:
            raise PerfUploadingError('URLError: %s for JSON %s\n' %
                                     (str(e.reason), data_obj['data']))
        except httplib.HTTPException:
            raise PerfUploadingError('HTTPException for JSON %s\n' %
                                     data_obj['data'])


    def _write_perf_keyvals(self, perf_results):
        """
        Write perf results to keyval file for AutoTest results.

        @param perf_results: dict of attribute performance metrics.

        """
        perf_keyval = {}
        perf_keyval['cpu_usage'] = perf_results['cpu']
        perf_keyval['memory_usage'] = perf_results['mem']
        perf_keyval['temperature'] = perf_results['temp']
        self.write_perf_keyval(perf_keyval)


    def _write_perf_results(self, perf_results):
        """
        Write perf results to results-chart.json file for Perf Dashboard.

        @param perf_results: dict of attribute performance metrics.

        """
        cpu_metric = perf_results['cpu']
        mem_metric = perf_results['mem']
        ec_metric = perf_results['temp']
        self.output_perf_value(description='cpu_usage', value=cpu_metric,
                               units='percent', higher_is_better=False)
        self.output_perf_value(description='mem_usage', value=mem_metric,
                               units='percent', higher_is_better=False)
        self.output_perf_value(description='max_temp', value=ec_metric,
                               units='Celsius', higher_is_better=False)


    def _record_perf_measurements(self, perf_values, perf_writer):
        """
        Record attribute performance measurements, and write to file.

        @param perf_values: dict of attribute performance values.
        @param perf_writer: file to write performance measurements.

        """
        # Get performance measurements.
        cpu_usage = '%.3f' % enterprise_longevity_helper.get_cpu_usage(
                self.system_facade, MEASUREMENT_DURATION_SECONDS)
        mem_usage = '%.3f' % enterprise_longevity_helper.get_memory_usage(
                    self.system_facade)
        max_temp = '%.3f' % enterprise_longevity_helper.get_temperature_data(
                self.client, self.system_facade)

        # Append measurements to attribute lists in perf values dictionary.
        perf_values['cpu'].append(float(cpu_usage))
        perf_values['mem'].append(float(mem_usage))
        perf_values['temp'].append(float(max_temp))

        # Write performance measurements to perf timestamped file.
        time_stamp = time.strftime('%Y/%m/%d %H:%M:%S')
        perf_writer.writerow([time_stamp, cpu_usage, mem_usage, max_temp])
        logging.info('Time: %s, CPU: %r, Mem: %r, Temp: %r',
                     time_stamp, cpu_usage, mem_usage, max_temp)


    def _setup_kiosk_app_on_dut(self, kiosk_app_attributes=None):
        """Enroll the DUT and setup a Kiosk app."""
        info = self.client.host_info_store.get()
        app_config_id = info.get_label_value('app_config_id')
        if app_config_id and app_config_id.startswith(':'):
            app_config_id = app_config_id[1:]
        if kiosk_app_attributes:
            kiosk_app_attributes = kiosk_app_attributes.rstrip()
            self.kiosk_app_name, ext_id = kiosk_app_attributes.split(':')[:2]

        tpm_utils.ClearTPMOwnerRequest(self.client)
        logging.info("Enrolling the DUT to Kiosk mode")
        autotest.Autotest(self.client).run_test(
                'enterprise_KioskEnrollment',
                kiosk_app_attributes=kiosk_app_attributes,
                check_client_result=True)

        #if self.kiosk_app_name == 'riseplayer':
        #    self.kiosk_facade.config_rise_player(ext_id, app_config_id)


    def _run_perf_capture_cycle(self):
        """
        Track performance of Chrome OS over a long period of time.

        This method collects performance measurements, and calculates metrics
        to upload to the performance dashboard. It creates two files to
        collect and store performance values and results: perf_<timestamp>.csv
        and perf_aggregated.csv.

        At the start, it creates a unique perf timestamped file in the test's
        temp_dir. As the cycle runs, it saves a time-stamped performance
        value after each sample interval. Periodically, it calculates
        the 90th percentile performance metrics from these values.

        The perf_<timestamp> files on the device will survive multiple runs
        of the longevity_Tracker by the server-side test, and will also
        survive multiple runs of the server-side test.

        At the end, it opens the perf aggregated file in the test's temp_dir,
        and appends the contents of the perf timestamped file. It then
        copies the perf aggregated file to the results directory as perf.csv.
        This perf.csv file will be consumed by the AutoTest backend when the
        server-side test ends.

        Note that the perf_aggregated.csv file will grow larger with each run
        of longevity_Tracker on the device by the server-side test.

        This method will capture perf metrics every SAMPLE_INTERVAL secs, at
        each METRIC_INTERVAL the 90 percentile of the collected metrics is
        calculated and saved. The perf capture runs for PERF_CAPTURE_DURATION
        secs. At the end of the PERF_CAPTURE_DURATION time interval the median
        value of all 90th percentile metrics is returned.

        @returns list of median performance metrics.

        """
        test_start_time = time.time()

        perf_values = {'cpu': [], 'mem': [], 'temp': []}
        perf_metrics = {'cpu': [], 'mem': [], 'temp': []}

         # Create perf_<timestamp> file and writer.
        timestamp_fname = (PERF_FILE_NAME_PREFIX +
                           time.strftime('_%Y-%m-%d_%H-%M') + '.csv')
        timestamp_fpath = os.path.join(self.temp_dir, timestamp_fname)
        timestamp_file = enterprise_longevity_helper.open_perf_file(
                timestamp_fpath)
        timestamp_writer = csv.writer(timestamp_file)

        # Align time of loop start with the sample interval.
        test_elapsed_time = self.elapsed_time(test_start_time)
        time.sleep(enterprise_longevity_helper.syncup_time(
                test_elapsed_time, self.sample_interval))
        test_elapsed_time = self.elapsed_time(test_start_time)

        metric_start_time = time.time()
        metric_prev_time = metric_start_time

        metric_elapsed_prev_time = self.elapsed_time(metric_prev_time)
        offset = enterprise_longevity_helper.modulo_time(
                metric_elapsed_prev_time, self.metric_interval)
        metric_timer = metric_elapsed_prev_time + offset

        while self.elapsed_time(test_start_time) <= self.perf_capture_duration:
            self._record_perf_measurements(perf_values, timestamp_writer)

            # Periodically calculate and record 90th percentile metrics.
            metric_elapsed_prev_time = self.elapsed_time(metric_prev_time)
            metric_timer = metric_elapsed_prev_time + offset
            if metric_timer >= self.metric_interval:
                enterprise_longevity_helper.record_90th_metrics(
                        perf_values, perf_metrics)
                perf_values = {'cpu': [], 'mem': [], 'temp': []}

            # Set previous time to current time.
                metric_prev_time = time.time()
                metric_elapsed_prev_time = self.elapsed_time(metric_prev_time)

                metric_elapsed_time = self.elapsed_time(metric_start_time)
                offset = enterprise_longevity_helper.modulo_time(
                    metric_elapsed_time, self.metric_interval)

                # Set the timer to time elapsed plus offset to next interval.
                metric_timer = metric_elapsed_prev_time + offset

            # Sync the loop time to the sample interval.
            test_elapsed_time = self.elapsed_time(test_start_time)
            time.sleep(enterprise_longevity_helper.syncup_time(
                    test_elapsed_time, self.sample_interval))

        # Close perf timestamp file.
        timestamp_file.close()

         # Open perf timestamp file to read, and aggregated file to append.
        timestamp_file = open(timestamp_fpath, 'r')
        aggregated_fname = (PERF_FILE_NAME_PREFIX + '_aggregated.csv')
        aggregated_fpath = os.path.join(self.temp_dir, aggregated_fname)
        aggregated_file = enterprise_longevity_helper.open_perf_file(
                aggregated_fpath)

         # Append contents of perf timestamp file to perf aggregated file.
        enterprise_longevity_helper.append_to_aggregated_file(
                timestamp_file, aggregated_file)
        timestamp_file.close()
        aggregated_file.close()

        # Copy perf aggregated file to test results directory.
        enterprise_longevity_helper.copy_aggregated_to_resultsdir(
                self.resultsdir, aggregated_fpath, 'perf.csv')

        # Return median of each attribute performance metric.
        logging.info("Perf_metrics: %r ", perf_metrics)
        return enterprise_longevity_helper.get_median_metrics(perf_metrics)


    def run_once(self, host=None, perf_params=None):
        self.client = host
        self.kiosk_app_name = None
        self.perf_params = perf_params
        logging.info('Perf params: %r', self.perf_params)

        if not enterprise_longevity_helper.verify_perf_params(
                EXPECTED_PARAMS, self.perf_params):
            raise error.TestFail('Missing or incorrect perf_params in the'
                                 ' control file. Refer to the README.txt for'
                                 ' info on perf params.: %r'
                                  %(self.perf_params))

        factory = remote_facade_factory.RemoteFacadeFactory(
                host, no_chrome=True)
        self.system_facade = factory.create_system_facade()
        self.kiosk_facade = factory.create_kiosk_facade()

        self._setup_kiosk_app_on_dut(self.perf_params['kiosk_app_attributes'])
        time.sleep(STABILIZATION_DURATION)

        self._initialize_test_variables()
        for iteration in range(self.perf_params['perf_capture_iterations']):
            #TODO(krishnargv@): Add a method to verify that the Kiosk app is
            #                   active and is running on the DUT.
            logging.info("Running perf_capture Iteration: %d", iteration+1)
            self.perf_results = self._run_perf_capture_cycle()
            self._write_perf_keyvals(self.perf_results)
            self._write_perf_results(self.perf_results)

            # Post perf results directly to performance dashboard. You may view
            # uploaded data at https://chromeperf.appspot.com/new_points,
            # with test path pattern=ChromeOS_Enterprise/cros-*/longevity*/*
            if perf_params['test_type'] == 'multiple_samples':
                chart_data = enterprise_longevity_helper.read_perf_results(
                        self.resultsdir, 'results-chart.json')
                data_obj = self._format_data_for_upload(chart_data)
                self._send_to_dashboard(data_obj)
        tpm_utils.ClearTPMOwnerRequest(self.client)
