#
#  Copyright (C) 2018 Codethink Limited
#
#  This program is free software; you can redistribute it and/or
#  modify it under the terms of the GNU Lesser General Public
#  License as published by the Free Software Foundation; either
#  version 2 of the License, or (at your option) any later version.
#
#  This library is distributed in the hope that it will be useful,
#  but WITHOUT ANY WARRANTY; without even the implied warranty of
#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the GNU
#  Lesser General Public License for more details.
#
#  You should have received a copy of the GNU Lesser General Public
#  License along with this library. If not, see <http://www.gnu.org/licenses/>.
#
#  Authors:
#        Tristan Van Berkom <tristan.vanberkom@codethink.co.uk>
import click
from blessings import Terminal

# Import a widget internal for formatting time codes
from .widget import TimeCode


# Status()
#
# A widget for formatting overall status.
#
# Note that the render() and clear() methods in this class are
# simply noops in the case that the application is not connected
# to a terminal, or if the terminal does not support ANSI escape codes.
#
# Args:
#    context (Context): The Context
#    content_profile (Profile): Formatting profile for content text
#    format_profile (Profile): Formatting profile for formatting text
#    success_profile (Profile): Formatting profile for success text
#    error_profile (Profile): Formatting profile for error text
#    stream (Stream): The Stream
#    colors (bool): Whether to print the ANSI color codes in the output
#
class Status():

    def __init__(self, context,
                 content_profile, format_profile,
                 success_profile, error_profile,
                 stream, colors=False):

        self._context = context
        self._content_profile = content_profile
        self._format_profile = format_profile
        self._success_profile = success_profile
        self._error_profile = error_profile
        self._stream = stream
        self._jobs = []
        self._last_lines = 0  # Number of status lines we last printed to console
        self._term = Terminal()
        self._spacing = 1
        self._colors = colors
        self._header = _StatusHeader(context,
                                     content_profile, format_profile,
                                     success_profile, error_profile,
                                     stream)

        self._term_width, _ = click.get_terminal_size()
        self._alloc_lines = 0
        self._alloc_columns = None
        self._line_length = 0
        self._need_alloc = True

    # add_job()
    #
    # Adds a job to track in the status area
    #
    # Args:
    #    element (Element): The element of the job to track
    #    action_name (str): The action name for this job
    #
    def add_job(self, element, action_name):
        elapsed = self._stream.elapsed_time
        job = _StatusJob(self._context, element, action_name, self._content_profile, self._format_profile, elapsed)
        self._jobs.append(job)
        self._need_alloc = True

    # remove_job()
    #
    # Removes a job currently being tracked in the status area
    #
    # Args:
    #    element (Element): The element of the job to track
    #    action_name (str): The action name for this job
    #
    def remove_job(self, element, action_name):
        self._jobs = [
            job for job in self._jobs
            if not (job.element is element and
                    job.action_name == action_name)
        ]
        self._need_alloc = True

    # clear()
    #
    # Clear the status area, it is necessary to call
    # this before printing anything to the console if
    # a status area is in use.
    #
    # To print some logging to the output and then restore
    # the status, use the following:
    #
    #   status.clear()
    #   ... print something to console ...
    #   status.render()
    #
    def clear(self):

        if not self._term.does_styling:
            return

        for _ in range(self._last_lines):
            self._move_up()
            self._clear_line()
        self._last_lines = 0

    # render()
    #
    # Render the status area.
    #
    # If you are not printing a line in addition to rendering
    # the status area, for instance in a timeout, then it is
    # not necessary to call clear().
    def render(self):

        if not self._term.does_styling:
            return

        elapsed = self._stream.elapsed_time

        self.clear()
        self._check_term_width()
        self._allocate()

        # Nothing to render, early return
        if self._alloc_lines == 0:
            return

        # Before rendering the actual lines, we need to add some line
        # feeds for the amount of lines we intend to print first, and
        # move cursor position back to the first line
        for _ in range(self._alloc_lines + self._header.lines):
            click.echo('', err=True)
        for _ in range(self._alloc_lines + self._header.lines):
            self._move_up()

        # Render the one line header
        text = self._header.render(self._term_width, elapsed)
        click.echo(text, color=self._colors, err=True)

        # Now we have the number of columns, and an allocation for
        # alignment of each column
        n_columns = len(self._alloc_columns)
        for line in self._job_lines(n_columns):
            text = ''
            for job in line:
                column = line.index(job)
                text += job.render(self._alloc_columns[column] - job.size, elapsed)

                # Add spacing between columns
                if column < (n_columns - 1):
                    text += ' ' * self._spacing

            # Print the line
            click.echo(text, color=self._colors, err=True)

        # Track what we printed last, for the next clear
        self._last_lines = self._alloc_lines + self._header.lines

    ###################################################
    #                 Private Methods                 #
    ###################################################
    def _check_term_width(self):
        term_width, _ = click.get_terminal_size()
        if self._term_width != term_width:
            self._term_width = term_width
            self._need_alloc = True

    def _move_up(self):
        # Explicitly move to beginning of line, fixes things up
        # when there was a ^C or ^Z printed to the terminal.
        click.echo(self._term.move_x(0) + self._term.move_up, nl=False, err=True)

    def _clear_line(self):
        click.echo(self._term.clear_eol, nl=False, err=True)

    def _allocate(self):
        if not self._need_alloc:
            return

        # State when there is no jobs to display
        alloc_lines = 0
        alloc_columns = []
        line_length = 0

        # Test for the widest width which fits columnized jobs
        for columns in reversed(range(len(self._jobs))):
            alloc_lines, alloc_columns = self._allocate_columns(columns + 1)

            # If the sum of column widths with spacing in between
            # fits into the terminal width, this is a good allocation.
            line_length = sum(alloc_columns) + (columns * self._spacing)
            if line_length < self._term_width:
                break

        self._alloc_lines = alloc_lines
        self._alloc_columns = alloc_columns
        self._line_length = line_length
        self._need_alloc = False

    def _job_lines(self, columns):
        for i in range(0, len(self._jobs), columns):
            yield self._jobs[i:i + columns]

    # Returns an array of integers representing the maximum
    # length in characters for each column, given the current
    # list of jobs to render.
    #
    def _allocate_columns(self, columns):
        column_widths = [0 for _ in range(columns)]
        lines = 0
        for line in self._job_lines(columns):
            line_len = len(line)
            lines += 1
            for col in range(columns):
                if col < line_len:
                    job = line[col]
                    column_widths[col] = max(column_widths[col], job.size)

        return lines, column_widths


# _StatusHeader()
#
# A delegate object for rendering the header part of the Status() widget
#
# Args:
#    context (Context): The Context
#    content_profile (Profile): Formatting profile for content text
#    format_profile (Profile): Formatting profile for formatting text
#    success_profile (Profile): Formatting profile for success text
#    error_profile (Profile): Formatting profile for error text
#    stream (Stream): The Stream
#
class _StatusHeader():

    def __init__(self, context,
                 content_profile, format_profile,
                 success_profile, error_profile,
                 stream):

        #
        # Public members
        #
        self.lines = 3

        #
        # Private members
        #
        self._content_profile = content_profile
        self._format_profile = format_profile
        self._success_profile = success_profile
        self._error_profile = error_profile
        self._stream = stream
        self._time_code = TimeCode(context, content_profile, format_profile)
        self._context = context

    def render(self, line_length, elapsed):
        project = self._context.get_toplevel_project()
        line_length = max(line_length, 80)
        size = 0
        text = ''

        session = str(len(self._stream.session_elements))
        total = str(len(self._stream.total_elements))

        # Format and calculate size for target and overall time code
        size += len(total) + len(session) + 4  # Size for (N/N) with a leading space
        size += 8  # Size of time code
        size += len(project.name) + 1
        text += self._time_code.render_time(elapsed)
        text += ' ' + self._content_profile.fmt(project.name)
        text += ' ' + self._format_profile.fmt('(') + \
                self._content_profile.fmt(session) + \
                self._format_profile.fmt('/') + \
                self._content_profile.fmt(total) + \
                self._format_profile.fmt(')')

        line1 = self._centered(text, size, line_length, '=')
        size = 0
        text = ''

        # Format and calculate size for each queue progress
        for queue in self._stream.queues:

            # Add spacing
            if self._stream.queues.index(queue) > 0:
                size += 2
                text += self._format_profile.fmt('→ ')

            queue_text, queue_size = self._render_queue(queue)
            size += queue_size
            text += queue_text

        line2 = self._centered(text, size, line_length, ' ')

        size = 24
        text = self._format_profile.fmt("~~~~~ ") + \
            self._content_profile.fmt('Active Tasks') + \
            self._format_profile.fmt(" ~~~~~")
        line3 = self._centered(text, size, line_length, ' ')

        return line1 + '\n' + line2 + '\n' + line3

    ###################################################
    #                 Private Methods                 #
    ###################################################
    def _render_queue(self, queue):
        processed = str(len(queue.processed_elements))
        skipped = str(len(queue.skipped_elements))
        failed = str(len(queue.failed_elements))

        size = 5  # Space for the formatting '[', ':', ' ', ' ' and ']'
        size += len(queue.complete_name)
        size += len(processed) + len(skipped) + len(failed)
        text = self._format_profile.fmt("(") + \
            self._content_profile.fmt(queue.complete_name) + \
            self._format_profile.fmt(":") + \
            self._success_profile.fmt(processed) + ' ' + \
            self._content_profile.fmt(skipped) + ' ' + \
            self._error_profile.fmt(failed) + \
            self._format_profile.fmt(")")

        return (text, size)

    def _centered(self, text, size, line_length, fill):
        remaining = line_length - size
        remaining -= 2

        final_text = self._format_profile.fmt(fill * (remaining // 2)) + ' '
        final_text += text
        final_text += ' ' + self._format_profile.fmt(fill * (remaining // 2))

        return final_text


# _StatusJob()
#
# A delegate object for rendering a job in the status area
#
# Args:
#    context (Context): The Context
#    element (Element): The element being processed
#    action_name (str): The name of the action
#    content_profile (Profile): Formatting profile for content text
#    format_profile (Profile): Formatting profile for formatting text
#    elapsed (datetime): The offset into the session when this job is created
#
class _StatusJob():

    def __init__(self, context, element, action_name, content_profile, format_profile, elapsed):

        #
        # Public members
        #
        self.element = element            # The Element
        self.action_name = action_name    # The action name
        self.size = None                  # The number of characters required to render

        #
        # Private members
        #
        self._offset = elapsed
        self._content_profile = content_profile
        self._format_profile = format_profile
        self._time_code = TimeCode(context, content_profile, format_profile)

        # Calculate the size needed to display
        self.size = 10  # Size of time code with brackets
        self.size += len(action_name)
        self.size += len(element._get_full_name())
        self.size += 3  # '[' + ':' + ']'

    # render()
    #
    # Render the Job, return a rendered string
    #
    # Args:
    #    padding (int): Amount of padding to print in order to align with columns
    #    elapsed (datetime): The session elapsed time offset
    #
    def render(self, padding, elapsed):
        text = self._format_profile.fmt('[') + \
            self._time_code.render_time(elapsed - self._offset) + \
            self._format_profile.fmt(']')

        # Add padding after the display name, before terminating ']'
        name = self.element._get_full_name() + (' ' * padding)
        text += self._format_profile.fmt('[') + \
            self._content_profile.fmt(self.action_name) + \
            self._format_profile.fmt(':') + \
            self._content_profile.fmt(name) + \
            self._format_profile.fmt(']')

        return text
