import sys


def create_display(opts, tests, total_tests, workers):
    if opts.quiet:
        return NopDisplay()

    of_total = (' of %d' % total_tests) if (tests != total_tests) else ''
    header = '-- Testing: %d%s tests, %d workers --' % (tests, of_total, workers)

    progress_bar = None
    if opts.succinct and opts.useProgressBar:
        import lit.ProgressBar
        try:
            tc = lit.ProgressBar.TerminalController()
            progress_bar = lit.ProgressBar.ProgressBar(tc, header)
            header = None
        except ValueError:
            progress_bar = lit.ProgressBar.SimpleProgressBar('Testing: ')

    return Display(opts, tests, header, progress_bar)


class NopDisplay(object):
    def print_header(self): pass
    def update(self, test): pass
    def clear(self, interrupted): pass


class Display(object):
    def __init__(self, opts, tests, header, progress_bar):
        self.opts = opts
        self.tests = tests
        self.header = header
        self.progress_bar = progress_bar
        self.completed = 0

    def print_header(self):
        if self.header:
            print(self.header)
        if self.progress_bar:
            self.progress_bar.update(0.0, '')

    def update(self, test):
        self.completed += 1

        show_result = test.isFailure() or \
                self.opts.showAllOutput or \
                (not self.opts.quiet and not self.opts.succinct)
        if show_result:
            if self.progress_bar:
                self.progress_bar.clear(interrupted=False)
            self.print_result(test)

        if self.progress_bar:
            if test.isFailure():
                self.progress_bar.barColor = 'RED'
            percent = float(self.completed) / self.tests
            self.progress_bar.update(percent, test.getFullName())

    def clear(self, interrupted):
        if self.progress_bar:
            self.progress_bar.clear(interrupted)

    def print_result(self, test):
        # Show the test result line.
        test_name = test.getFullName()
        print('%s: %s (%d of %d)' % (test.result.code.name, test_name,
                                     self.completed, self.tests))

        # Show the test failure output, if requested.
        if (test.isFailure() and self.opts.showOutput) or \
           self.opts.showAllOutput:
            if test.isFailure():
                print("%s TEST '%s' FAILED %s" % ('*'*20, test.getFullName(),
                                                  '*'*20))
            out = test.result.output
            # Encode/decode so that, when using Python 3.6.5 in Windows 10,
            # print(out) doesn't raise UnicodeEncodeError if out contains
            # special characters.  However, Python 2 might try to decode
            # as part of the encode call if out is already encoded, so skip
            # encoding if it raises UnicodeDecodeError.
            if sys.stdout.encoding:
                try:
                    out = out.encode(encoding=sys.stdout.encoding,
                                     errors="replace")
                except UnicodeDecodeError:
                    pass
                # Python 2 can raise UnicodeDecodeError here too in cases
                # where the stdout encoding is ASCII. Ignore decode errors
                # in this case.
                out = out.decode(encoding=sys.stdout.encoding, errors="ignore")
            print(out)
            print("*" * 20)

        # Report test metrics, if present.
        if test.result.metrics:
            print("%s TEST '%s' RESULTS %s" % ('*'*10, test.getFullName(),
                                               '*'*10))
            items = sorted(test.result.metrics.items())
            for metric_name, value in items:
                print('%s: %s ' % (metric_name, value.format()))
            print("*" * 10)

        # Report micro-tests, if present
        if test.result.microResults:
            items = sorted(test.result.microResults.items())
            for micro_test_name, micro_test in items:
                print("%s MICRO-TEST: %s" %
                         ('*'*3, micro_test_name))

                if micro_test.metrics:
                    sorted_metrics = sorted(micro_test.metrics.items())
                    for metric_name, value in sorted_metrics:
                        print('    %s:  %s ' % (metric_name, value.format()))

        # Ensure the output is flushed.
        sys.stdout.flush()
