# Source code for stestr.commands.slowest

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

    """Show the longest running tests in the repository."""

    import math
    from operator import itemgetter
    import sys

    from cliff import command

    from stestr import output
    from stestr.repository import util

    class Slowest(command.Command):
        """Show the slowest tests from the last test run.

        This command shows a table, with the longest running tests at the top.
        """

        def get_parser(self, prog_name):
            parser = super().get_parser(prog_name)
            parser.add_argument(
                "--all", action="store_true",
                default=False, help="Show timing for all tests.")
            return parser

        def take_action(self, parsed_args):
            args = parsed_args
            return slowest(repo_type=self.app_args.repo_type,
                           repo_url=self.app_args.repo_url,
                           show_all=args.all)

    def format_times(times):
        times = list(times)
        precision = 3
        digits_before_point = 1
        for time in times:
            if time[1] <= 0:
                continue
            digits_before_point = int(math.log10(time[1])) + 1
            break
        min_length = digits_before_point + precision + 1

        def format_time(time):
            # Limit the number of digits after the decimal
            # place, and also enforce a minimum width
            # based on the longest duration
            return "%*.*f" % (min_length, precision, time)
        times = [(name, format_time(time)) for name, time in times]
        return times

    def slowest(repo_type='file', repo_url=None, show_all=False,
                stdout=sys.stdout):
        """Print the slowest times from the last run in the repository

        This function will print to STDOUT the 10 slowests tests in the last run.
        Optionally, using the ``show_all`` argument, it will print all the tests,
        instead of just 10. sorted by time.

        :param str repo_type: This is the type of repository to use. Valid choices
            are 'file' and 'sql'.
        :param str repo_url: The url of the repository to use.
        :param bool show_all: Show timing for all tests.
        :param file stdout: The output file to write all output to. By default
            this is sys.stdout

        :return return_code: The exit code for the command. 0 for success and > 0
            for failures.
        :rtype: int
        """

        repo = util.get_repo_open(repo_type, repo_url)
        try:
            latest_id = repo.latest_id()
        except KeyError:
            return 3
        # what happens when there is no timing info?
        test_times = repo.get_test_times(repo.get_test_ids(latest_id))
        known_times = list(test_times['known'].items())
        known_times.sort(key=itemgetter(1), reverse=True)
        if len(known_times) > 0:
            # By default show 10 rows
            if not show_all:
                known_times = known_times[:10]
            known_times = format_times(known_times)
            header = ('Test id', 'Runtime (s)')
            rows = [header] + known_times
            output.output_table(rows, output=stdout)
        return 0