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

import dbus
import gzip
import logging
import os
import subprocess
import shutil
import tempfile

from autotest_lib.client.bin import test
from autotest_lib.client.common_lib import error
from autotest_lib.client.common_lib import file_utils
from autotest_lib.client.cros import debugd_util

import archiver
import configurator
import helpers
import fake_printer
import log_reader
import multithreaded_processor

# Timeout for printing documents in seconds
_FAKE_PRINTER_TIMEOUT = 200

# Prefix for CUPS printer name
_FAKE_PRINTER_ID = 'FakePrinter'

# First port number to use, this test uses consecutive ports numbers,
# different for every PPD file
_FIRST_PORT_NUMBER = 9000

# Values are from platform/system_api/dbus/debugd/dbus-constants.h.
_CUPS_SUCCESS = 0

class platform_PrinterPpds(test.test):
    """
    This test gets a list of PPD files and a list of test documents. It tries
    to add printer using each PPD file and to print all test documents on
    every printer created this way. Becasue the number of PPD files to test can
    be large (more then 3K), PPD files are tested simultaneously in many
    threads.

    """
    version = 3


    def _get_filenames_from_PPD_indexes(self):
        """
        It returns all PPD filenames from SCS server.

        @returns a list of PPD filenames without duplicates

        """
        # extracts PPD filenames from all 20 index files (in parallel)
        outputs = self._processor.run(helpers.get_filenames_from_PPD_index, 20)
        # joins obtained lists and performs deduplication
        ppd_files = set()
        for output in outputs:
            ppd_files.update(output)
        return list(ppd_files)


    def _calculate_full_path(self, path):
        """
        Converts path given as a parameter to absolute path.

        @param path: a path set in configuration (relative, absolute or None)

        @returns absolute path or None if the input parameter was None

        """
        if path is None or os.path.isabs(path):
            return path
        path_current = os.path.dirname(os.path.realpath(__file__))
        return os.path.join(path_current, path)


    def initialize(self,
                   path_docs,
                   path_ppds,
                   path_digests=None,
                   debug_mode=False,
                   threads_count=8):
        """
        @param path_docs: path to local directory with documents to print
        @param path_ppds: path to local directory with PPD files to test;
                the directory is supposed to be compressed as .tar.xz.
        @param path_digests: path to local directory with digests files for
                test documents; if None is set then content of printed
                documents is not verified
        @param debug_mode: if set to True, then the autotest temporarily
                remounts the root partition in R/W mode and changes CUPS
                configuration, what allows to extract pipelines for all tested
                PPDs and rerun the outside CUPS
        @param threads_count: number of threads to use

        """
        # Calculates absolute paths for all parameters
        self._location_of_test_docs = self._calculate_full_path(path_docs)
        self._location_of_PPD_files = self._calculate_full_path(path_ppds)
        location_of_digests_files = self._calculate_full_path(path_digests)

        # This object is used for running tasks in many threads simultaneously
        self._processor = multithreaded_processor.MultithreadedProcessor(
                threads_count)

        # This object is responsible for parsing CUPS logs
        self._log_reader = log_reader.LogReader()

        # This object is responsible for the system configuration
        self._configurator = configurator.Configurator()
        self._configurator.configure(debug_mode)

        # Read list of test documents
        self._docs = helpers.list_entries_from_directory(
                            path=self._location_of_test_docs,
                            with_suffixes=('.pdf'),
                            nonempty_results=True,
                            include_directories=False)

        # Load the list of PPD files to omit
        do_not_test_path = self._calculate_full_path('do_not_test.txt')
        do_not_test_set = set(helpers.load_lines_from_file(do_not_test_path))

        # Unpack an archive with the PPD files:
        path_archive = self._location_of_PPD_files + '.tar.xz'
        path_target_dir = self._calculate_full_path('.')
        file_utils.rm_dir_if_exists(os.path.join(path_target_dir, path_ppds))
        subprocess.call(['tar', 'xJf', path_archive, '-C', path_target_dir])
        # Load PPD files from the unpacked directory
        self._ppds = helpers.list_entries_from_directory(
                path=self._location_of_PPD_files,
                with_suffixes=('.ppd', '.ppd.gz'),
                nonempty_results=True,
                include_directories=False)
        # Remove from the list all PPD files to omit and sort it
        self._ppds = list(set(self._ppds) - do_not_test_set)
        self._ppds.sort()

        # Load digests files
        self._digests = dict()
        if location_of_digests_files is None:
            for doc_name in self._docs:
                self._digests[doc_name] = dict()
        else:
            path_denylist = os.path.join(location_of_digests_files,
                                         'denylist.txt')
            denylist = helpers.load_lines_from_file(path_denylist)
            for doc_name in self._docs:
                digests_name = doc_name + '.digests'
                path = os.path.join(location_of_digests_files, digests_name)
                self._digests[doc_name] = helpers.parse_digests_file(
                        path, denylist)

        # Prepare a working directory for pipelines
        if debug_mode:
            self._pipeline_dir = tempfile.mkdtemp(dir='/tmp')
        else:
            self._pipeline_dir = None


    def cleanup(self):
        """
        Cleanup.

        """
        # Resore previous system settings
        self._configurator.restore()

        # Delete directories with PPD files
        path_ppds = self._calculate_full_path('ppds_100')
        file_utils.rm_dir_if_exists(path_ppds)
        path_ppds = self._calculate_full_path('ppds_all')
        file_utils.rm_dir_if_exists(path_ppds)

        # Delete pipeline working directory
        if self._pipeline_dir is not None:
            file_utils.rm_dir_if_exists(self._pipeline_dir)


    def run_once(self, path_outputs=None):
        """
        This is the main test function. It runs the testing procedure for
        every PPD file. Tests are run simultaneously in many threads.

        @param path_outputs: if it is not None, raw outputs sent
                to printers are dumped here; the directory is overwritten if
                already exists (is deleted and recreated)

        @raises error.TestFail if at least one of the tests failed

        """
        # Set directory for output documents
        self._path_output_directory = self._calculate_full_path(path_outputs)
        if self._path_output_directory is not None:
            # Delete whole directory if already exists
            file_utils.rm_dir_if_exists(self._path_output_directory)
            # Create archivers
            self._archivers = dict()
            for doc_name in self._docs:
                path_for_archiver = os.path.join(self._path_output_directory,
                        doc_name)
                self._archivers[doc_name] = archiver.Archiver(path_for_archiver,
                        self._ppds, 50)
            # A place for new digests
            self._new_digests = dict()
            for doc_name in self._docs:
                self._new_digests[doc_name] = dict()

        # Runs tests for all PPD files (in parallel)
        outputs = self._processor.run(self._thread_test_PPD, len(self._ppds))

        # Analyses tests' outputs, prints a summary report and builds a list
        # of PPD filenames that failed
        failures = []
        for i, output in enumerate(outputs):
            ppd_file = self._ppds[i]
            if output != True:
                failures.append(ppd_file)
            else:
                output = 'OK'
            line = "%s: %s" % (ppd_file, output)
            logging.info(line)

        # Calculate digests files for output documents (if dumped)
        if self._path_output_directory is not None:
            for doc_name in self._docs:
                path = os.path.join(self._path_output_directory,
                        doc_name + '.digests')
                helpers.save_digests_file(path, self._new_digests[doc_name],
                        failures)

        # Raises an exception if at least one test failed
        if len(failures) > 0:
            failures.sort()
            raise error.TestFail(
                    'Test failed for %d PPD files: %s'
                    % (len(failures), ', '.join(failures)) )


    def _thread_test_PPD(self, task_id):
        """
        Runs a test procedure for single PPD file.

        It retrieves assigned PPD file and run for it a test procedure.

        @param task_id: an index of the PPD file in self._ppds

        @returns True when the test was passed or description of the error
                (string) if the test failed

        """
        # Gets content of the PPD file
        try:
            ppd_file = self._ppds[task_id]
            if self._location_of_PPD_files is None:
                # Downloads PPD file from the SCS server
                ppd_content = helpers.download_PPD_file(ppd_file)
            else:
                # Reads PPD file from local filesystem
                path_ppd = os.path.join(self._location_of_PPD_files, ppd_file)
                with open(path_ppd, 'rb') as ppd_file_descriptor:
                    ppd_content = ppd_file_descriptor.read()
        except BaseException as e:
            return 'MISSING PPD: ' + str(e)

        # Runs the test procedure
        try:
            port = _FIRST_PORT_NUMBER + task_id
            self._PPD_test_procedure(ppd_file, ppd_content, port)
        except BaseException as e:
            return 'FAIL: ' + str(e)

        return True


    def _PPD_test_procedure(self, ppd_name, ppd_content, port):
        """
        Test procedure for single PPD file.

        It tries to run the following steps:
        1. Starts an instance of FakePrinter
        2. Configures CUPS printer
        3. For each test document run the following steps:
            3a. Sends tests documents to the CUPS printer
            3b. Fetches the raw document from the FakePrinter
            3c. Parse CUPS logs and check for any errors
            3d. If self._pipeline_dir is set, extract the executed CUPS
                pipeline, rerun it in bash console and verify every step and
                final output
            3e. If self._path_output_directory is set, save the raw document
                and all intermediate steps in the provided directory
            3f. If the digest is available, verify a digest of an output
                documents
        4. Removes CUPS printer and stops FakePrinter
        If the test fails this method throws an exception.

        @param ppd_name: a name of the PPD file
        @param ppd_content: a content of the PPD file
        @param port: a port for the printer

        @throws Exception when the test fails

        """
        # Create work directory for external pipelines and save the PPD file
        # there (if needed)
        path_ppd = None
        if self._pipeline_dir is not None:
            path_pipeline_ppd_dir = os.path.join(self._pipeline_dir, ppd_name)
            os.makedirs(path_pipeline_ppd_dir)
            path_ppd = os.path.join(path_pipeline_ppd_dir, ppd_name)
            with open(path_ppd, 'wb') as file_ppd:
                file_ppd.write(ppd_content)
            if path_ppd.endswith('.gz'):
                subprocess.call(['gzip', '-d', path_ppd])
                path_ppd = path_ppd[0:-3]

        try:
            # Starts the fake printer
            with fake_printer.FakePrinter(port) as printer:

                # Add a CUPS printer manually with given ppd file
                cups_printer_id = '%s_at_%05d' % (_FAKE_PRINTER_ID,port)
                result = debugd_util.iface().CupsAddManuallyConfiguredPrinter(
                                             cups_printer_id,
                                             'socket://127.0.0.1:%d' % port,
                                             dbus.ByteArray(ppd_content))
                if result != _CUPS_SUCCESS:
                    raise Exception('valid_config - Could not setup valid '
                        'printer %d' % result)

                # Prints all test documents
                try:
                    for doc_name in self._docs:
                        # Full path to the test document
                        path_doc = os.path.join(
                                        self._location_of_test_docs, doc_name)
                        # Sends test document to printer
                        argv = ['lp', '-d', cups_printer_id]
                        argv += [path_doc]
                        subprocess.call(argv)
                        # Prepare a workdir for the pipeline (if needed)
                        path_pipeline_workdir_temp = None
                        if self._pipeline_dir is not None:
                            path_pipeline_workdir = os.path.join(
                                    path_pipeline_ppd_dir, doc_name)
                            path_pipeline_workdir_temp = os.path.join(
                                    path_pipeline_workdir, 'temp')
                            os.makedirs(path_pipeline_workdir_temp)
                        # Gets the output document from the fake printer
                        doc = printer.fetch_document(_FAKE_PRINTER_TIMEOUT)
                        digest = helpers.calculate_digest(doc)
                        # Retrive data from the log file
                        no_errors, logs, pipeline = \
                                self._log_reader.extract_result(
                                        cups_printer_id, path_ppd, path_doc,
                                        path_pipeline_workdir_temp)
                        # Archive obtained results in the output directory
                        if self._path_output_directory is not None:
                            self._archivers[doc_name].save_file(
                                    ppd_name, '.out', doc, apply_gzip=True)
                            self._archivers[doc_name].save_file(
                                    ppd_name, '.log', logs)
                            if pipeline is not None:
                                self._archivers[doc_name].save_file(
                                        ppd_name, '.sh', pipeline)
                            # Set new digest
                            self._new_digests[doc_name][ppd_name] = digest
                        # Fail if any of CUPS filters failed
                        if not no_errors:
                            raise Exception('One of the CUPS filters failed')
                        # Reruns the pipeline and dump intermediate outputs
                        if self._pipeline_dir is not None:
                            self._rerun_whole_pipeline(
                                        pipeline, path_pipeline_workdir,
                                        ppd_name, doc_name, digest)
                            shutil.rmtree(path_pipeline_workdir)
                        # Check document's digest (if known)
                        if ppd_name in self._digests[doc_name]:
                            digest_expected = self._digests[doc_name][ppd_name]
                            if digest_expected != digest:
                                message = 'Document\'s digest does not match'
                                raise Exception(message)
                        else:
                            # Simple validation
                            if len(doc) < 16:
                                raise Exception('Empty output')
                finally:
                    # Remove CUPS printer
                    debugd_util.iface().CupsRemovePrinter(cups_printer_id)

            # The fake printer is stopped at the end of "with" statement
        finally:
            # Finalize archivers and cleaning
            if self._path_output_directory is not None:
                for doc_name in self._docs:
                    self._archivers[doc_name].finalize_prefix(ppd_name)
            # Clean the pipelines' working directories
            if self._pipeline_dir is not None:
                shutil.rmtree(path_pipeline_ppd_dir)


    def _rerun_whole_pipeline(
            self, pipeline, path_workdir, ppd_name, doc_name, digest):
        """
        Reruns the whole pipeline outside CUPS server.

        Reruns a printing pipeline dumped from CUPS. All intermediate outputs
        are dumped and archived for future analysis.

        @param pipeline: a pipeline as a bash script
        @param path_workdir: an existing directory to use as working directory
        @param ppd_name: a filenames prefix used for archivers
        @param doc_name: a document name, used to select a proper archiver
        @param digest: an digest of the output produced by CUPS (for comparison)

        @raises Exception in case of any errors

        """
        # Save pipeline to a file
        path_pipeline = os.path.join(path_workdir, 'pipeline.sh')
        with open(path_pipeline, 'wb') as file_pipeline:
            file_pipeline.write(pipeline)
        # Run the pipeline
        argv = ['/bin/bash', '-e', path_pipeline]
        ret = subprocess.Popen(argv, cwd=path_workdir).wait()
        # Find the number of output files
        i = 1
        while os.path.isfile(os.path.join(path_workdir, "%d.doc.gz" % i)):
            i += 1
        files_count = i-1
        # Reads the last output (to compare it with the output produced by CUPS)
        if ret == 0:
            with gzip.open(os.path.join(path_workdir,
                    "%d.doc.gz" % files_count)) as last_file:
                content_digest = helpers.calculate_digest(last_file.read())
        # Archives all intermediate files (if desired)
        if self._path_output_directory is not None:
            for i in range(1,files_count+1):
                self._archivers[doc_name].move_file(ppd_name, ".err%d" % i,
                        os.path.join(path_workdir, "%d.err" % i))
                self._archivers[doc_name].move_file(ppd_name, ".out%d.gz" % i,
                        os.path.join(path_workdir, "%d.doc.gz" % i))
        # Validation
        if ret != 0:
            raise Exception("A pipeline script returned %d" % ret)
        if content_digest != digest:
            raise Exception("The output returned by the pipeline is different"
                    " than the output produced by CUPS")
