# Copyright 2021 The Debusine Developers
# See the AUTHORS file at the top-level directory of this distribution
#
# This file is part of Debusine. It is subject to the license terms
# in the LICENSE file found in the top-level directory of this
# distribution. No part of Debusine, including this file, may be copied,
# modified, propagated, or distributed except according to the terms
# contained in the LICENSE file.

"""Utility methods used in management module."""

from tabulate import tabulate


def print_tokens(output_file, tokens):
    """Print tokens (table formatted) to output_file."""
    headers = ['Token hash', 'User', 'Created', 'Enabled', 'Comment']
    table = []

    for token in tokens.order_by('user__username', 'created_at'):
        table.append(
            [
                token.hash,
                token.user.username if token.user is not None else "-",
                token.created_at.isoformat(),
                token.enabled,
                token.comment,
            ]
        )

    output_file.write(tabulate(table, headers))
    output_file.write()
    output_file.write(f'Number of tokens: {len(table)}')


def print_workers(output_file, workers):
    """Print workers (table formatted) to output_file."""
    headers = ['Name', 'Registered', 'Connected', 'Token hash', 'Enabled']
    table = []

    for worker in workers.order_by('registered_at'):
        token = worker.token
        table.append(
            [
                worker.name,
                datetime_to_isoformat(worker.registered_at),
                datetime_to_isoformat(worker.connected_at),
                token.hash if token is not None else "-",
                token.enabled if token is not None else True,
            ]
        )

    output_file.write(tabulate(table, headers))
    output_file.write()
    output_file.write(f'Number of workers: {len(table)}')


def print_workspaces(output_file, workspaces):
    """Print workspaces (table formatted) to output_file."""
    headers = [
        'Name',
        'Public',
        'Default Expiration Delay (days)',
        'Default File Store',
        '# Other File Stores',
    ]
    table = []

    for workspace in workspaces.order_by('id'):
        store_desc = (
            f"{workspace.default_file_store.name}"
            f" ({workspace.default_file_store.backend})"
        )
        table.append(
            [
                workspace.name,
                workspace.public,
                workspace.default_expiration_delay.days or "Never",
                store_desc,
                workspace.other_file_stores.count(),
            ]
        )

    output_file.write(tabulate(table, headers))
    output_file.write()
    output_file.write(f'Number of workspaces: {len(table)}')


def print_work_requests(output_file, work_requests):
    """Print work_requests formatted as a table to output_file."""
    headers = [
        "id",
        "worker",
        "created_at",
        "started_at",
        "completed_at",
        "status",
        "result",
    ]
    table = []

    for work_request in work_requests.order_by("created_at"):
        worker_name = work_request.worker.name if work_request.worker else "-"

        table.append(
            [
                work_request.id,
                worker_name,
                datetime_to_isoformat(work_request.created_at),
                datetime_to_isoformat(work_request.started_at),
                datetime_to_isoformat(work_request.completed_at),
                work_request.status,
                value_or_dash(work_request.result),
            ]
        )

    output_file.write(tabulate(table, headers))
    output_file.write()
    output_file.write(f'Number of work requests: {len(table)}')


def print_users(output_file, users):
    """Print users formatted as a table to output_file."""
    headers = ["username", "email", "date_joined"]

    table = []

    for user in users.order_by("date_joined"):
        table.append(
            [user.username, user.email, datetime_to_isoformat(user.date_joined)]
        )

    output_file.write(tabulate(table, headers))
    output_file.write()
    output_file.write(f"Number of users: {len(table)}")


def print_notification_channels(output_file, notification_channels):
    """Print notification channels formatted as a table to output_file."""
    headers = ["name", "method", "data"]

    table = []

    for notification_channel in notification_channels.order_by("name"):
        table.append(
            [
                notification_channel.name,
                notification_channel.method,
                notification_channel.data,
            ]
        )

    output_file.write(tabulate(table, headers))
    output_file.write()
    output_file.write(f"Number of notification channels: {len(table)}")


def datetime_to_isoformat(date_time) -> str:
    """Return date_time.isoformat() or - if it was None."""
    if date_time is None:
        return "-"

    return date_time.isoformat()


def value_or_dash(value):
    """Return the value if it is not None or -."""
    if value is None:
        return "-"

    return value
