#!/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):
    """Retreive jobs and services and display them."""
    if args.show_events:
        return display_events(client.events())

    return "".join([
        display.DisplayServices().format(client.services()),
        '\n',
        display.DisplayJobs().format(client.jobs()),
    ])


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)


def view_service(args, service_id, client):
    """Retrieve details of the specified service and display"""
    if args.show_events:
        return display_events(client.object_events(service_id.url))

    service_content = client.service(service_id.url)
    return display.format_service_details(service_content)


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


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()
