# 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.
        # TODO b:169251326 terms below are set outside of this codebase and
        # should be updated when possible ("master" -> "main").
        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)
