#!/usr/bin/env python
from __future__ import absolute_import
from __future__ import print_function
from __future__ import unicode_literals

import os
import sys

import argcomplete

from tron.commands import cmd_utils
from tron.commands import display
from tron.commands.client import Client
from tron.commands.client import get_object_type_from_identifier
from tron.commands.client import TronObjectType
from tron.commands.cmd_utils import ExitCode


def parse_cli():
    parser = cmd_utils.build_option_parser()
    parser.add_argument(
        "--numshown",
        "-n",
        type=int,
        dest="num_displays",
        help="Max number of jobs/job-runs shown",
        default=10,
    )
    parser.add_argument(
        "--color",
        "-c",
        action="store_true",
        dest="display_color",
        help="Display in color",
        default=None,
    )
    parser.add_argument(
        "--nocolor",
        action="store_false",
        dest="display_color",
        help="Display without color",
        default=None,
    )
    parser.add_argument(
        "--stdout",
        "-o",
        action="count",
        dest="stdout",
        help="Solely displays stdout",
        default=0,
    )
    parser.add_argument(
        "--stderr",
        "-e",
        action="count",
        dest="stderr",
        help="Solely displays stderr",
        default=0,
    )
    parser.add_argument(
        "--events",
        action="store_true",
        dest="show_events",
        help="Show events for the specified entity",
        default=False,
    )
    parser.add_argument(
        'name',
        nargs='?',
        help='job name | job run id | action id',
    ).completer = cmd_utils.tron_jobs_completer

    argcomplete.autocomplete(parser)
    args = parser.parse_args()
    return args


def console_height():
    if not sys.stdout.isatty():
        return 40
    return int(os.popen('stty size', 'r').read().split()[0])


def display_events(data):
    return display.DisplayEvents().format(data)


def view_all(args, client):
    """Retrieve jobs and display them."""
    if args.show_events:
        return display_events(client.events())

    return display.DisplayJobs().format(
        client.jobs(
            include_job_runs=False,
            include_action_runs=False,
            include_action_graph=False,
            include_node_pool=False,
        )
    )


def view_job(args, job_id, client):
    """Retrieve details of the specified job and display"""
    if args.show_events:
        return display_events(client.object_events(job_id.url))

    job_content = client.job(job_id.url, count=args.num_displays)
    return display.format_job_details(job_content)


def view_job_run(args, job_run_id, client):
    if args.show_events:
        return display_events(client.object_events(job_run_id.url))

    actions = client.job_runs(job_run_id.url)
    display_action = display.DisplayActionRuns()
    return display_action.format(actions)


def view_action_run(args, act_run_id, client):
    content = client.action_runs(
        act_run_id.url,
        num_lines=args.num_displays,
    )
    return display.format_action_run_details(content)


obj_type_to_view_map = {
    TronObjectType.job: view_job,
    TronObjectType.job_run: view_job_run,
    TronObjectType.action_run: view_action_run,
}


def get_view_output(name, args, client):
    url_index = client.index()
    tron_id = get_object_type_from_identifier(url_index, name)

    if tron_id.type not in obj_type_to_view_map:
        return
    return obj_type_to_view_map[tron_id.type](args, tron_id, client)


def main():
    """run tronview"""
    args = parse_cli()
    cmd_utils.setup_logging(args)
    cmd_utils.load_config(args)

    display.Color.toggle(args.display_color)
    client = Client(args.server)

    if not args.name:
        output = view_all(args, client)
    else:
        output = get_view_output(args.name, args, client)

    if not output:
        print("Unrecognized identifier: %s" % args.name, file=sys.stderr)
        sys.exit(ExitCode.fail)

    if sys.stdout.isatty() and len(output.split('\n')) > console_height():
        display.view_with_less(output, args.display_color)
    else:
        print(output)


if __name__ == '__main__':
    main()
