#!/usr/bin/env python
"""
Tool for querying the status of Scan Service.
"""
from __future__ import print_function

import os
import urllib2
import json
import sys
import argparse
import sqlite3

from collections import namedtuple

DB_PATH = os.environ.get("SCAN_SERVICE_DB_PATH", "/var/lib/radarscan/scans.sqlite")
API_URL = os.environ.get("SCAN_SERVICE_API_BASEURL", "http://localhost:34280/api/v0/")

def namedtuple_factory(cursor, row):
    fields = [col[0] for col in cursor.description]
    Row = namedtuple("Row", fields)
    return Row(*row)

def db_conn(file_path):
    conn = sqlite3.connect(file_path, detect_types=sqlite3.PARSE_DECLTYPES)
    conn.row_factory = namedtuple_factory
    # http://stackoverflow.com/a/27165929
    conn.execute("PRAGMA busy_timeout = %i" % 10000)
    return conn


def radars_overview(args):
    sources = json.loads(urllib2.urlopen(u"{}sources/".format(API_URL)).read())
    fmt = u"{:<8}\t{:<30}\t{:<30}"
    print(fmt.format("RADAR ID", "RADAR NAME", "LATEST SCAN"))
    for source in sources["sources"]:
        print(fmt.format(source["id"], source["name"], source["customData"]["latestScan"]))

def scans_for_radar(args):
    parser = argparse.ArgumentParser(description='Scan Service status tool / scans-for-site')
    parser.add_argument('radar_id', metavar='ID')
    parser.add_argument('--skip-header', action='store_true', default=False)
    args = parser.parse_args(args)

    conn = db_conn(DB_PATH)
    cursor = conn.cursor()

    fmt = u"{:<4}\t{:<20}\t{:<20}\t{:<10}\t{:<10}"
    if not args.skip_header:
        print(fmt.format("ID", "TASK", "TIMESTAMP", "HYBRID PART", "HYBRID ID"))
    for row in cursor.execute(
            """
SELECT radar_id, task_name, timestamp, hybrid_minor_task_id, hybrid_cardinality, hybrid_id
 FROM scans
 WHERE radar_id=:radar_id
 ORDER BY timestamp ASC;
""", {'radar_id': args.radar_id}):
        try:
            print(fmt.format(row.radar_id, row.task_name,
                             row.timestamp.strftime("%Y-%m-%dT%H:%M:%S"),
                             u"{}/{}".format(row.hybrid_minor_task_id, row.hybrid_cardinality),
                             row.hybrid_id))
        except IOError, ioe:
            if "Broken pipe" in str(ioe):
                return
            else:
                raise ioe

    cursor.close()
    conn.close()


def main():
    command_map = {'radars-overview': radars_overview,
                   'scans-for-radar': scans_for_radar}

    parser = argparse.ArgumentParser(description='Scan Service status tool')
    parser.add_argument('command', metavar='COMMAND', choices=command_map.keys(),
                        help='command to run (choose from ' + ", ".join(command_map.keys()) + ')')

    if len(sys.argv) > 1:
        args = parser.parse_args(args=sys.argv[1:2])
    elif len(sys.argv) == 1:
        args = parser.parse_args(args=sys.argv[1:])

    command_map[args.command](sys.argv[2:])

if __name__ == '__main__':
    main()
