#!/usr/bin/env python
# -*- mode: python; coding: utf-8 -*-
"""
Retrieve information from VOC

Usage:
  voc (-h | --help)
  voc --version
  voc [-v|-vv] [options] list
  voc [-v|-vv] [options] status
  voc [-v|-vv] [options] print [<attribute>]
  voc [-v|-vv] [options] (lock | unlock)
  voc [-v|-vv] [options] heater (start | stop)
  voc [-v|-vv] [options] call <method>

Options:
  -u <username>     VOC username
  -p <password>     VOC password
  -i <vin>          Vehicle VIN or registration number
  -g                Geolocate position
  -h --help         Show this message
  -v,-vv            Increase verbosity
  --version         Show version
"""

import docopt
import logging
from collections import OrderedDict
from datetime import datetime
import json

from volvooncall import __version__, read_credentials, Connection

_LOGGER = logging.getLogger(__name__)

def lookup_position(lat, lon):
    try:
        from geopy.geocoders import Nominatim
        geolocator = Nominatim()
        return geolocator.reverse((lat, lon))
    except ImportError:
        _LOGGER.info('geopy not installed. position lookup not available')

def print_vehicle(vehicle, geolocate=False):
    s = '%s %dkm' % (
        vehicle,
        vehicle.odometer / 1000)

    if vehicle.fuel_amount_level:
        s += ' (fuel %s%% %skm)' % (
            vehicle.fuel_amount_level,
            vehicle.distance_to_empty)

    print(s)

    try:
        lat, lon = (vehicle.position['latitude'],
                    vehicle.position['longitude'])
        pos = lookup_position(lat, lon) if geolocate else None
        if pos:
            print('    position: %.14f,%.14f (%s)' % (lat, lon, pos.address))
        else:
            print('    position: %.14f,%.14f' % (lat, lon))
    except AttributeError:
        pass

    print('    locked: %s' % ('yes' if vehicle.is_locked else 'no'))
    print('    heater: %s' % ('on' if vehicle.is_heater_on else 'off'))


def main():
    """Command line interface."""

    args = docopt.docopt(__doc__,
                         version=__version__)

    if args['-v'] == 2:
        level=logging.DEBUG
    elif args['-v']:
        level=logging.INFO
    else:
        level=logging.ERROR

    FORMAT = '%(asctime)s %(name)s: %(message)s'
    logging.basicConfig(level=level, format=FORMAT, datefmt='%H:%M:%S')

    if args['-u'] and args['-p']:
        connection = Connection(args['-u'],
                                args['-p'])
    else:
        credentials = read_credentials()
        if not credentials:
            exit('Could not read credentials and none supplied.')
        connection = Connection(**credentials)

    if not connection.update():
        exit('Could not connect to the server.')

    if args['list']:
        for vehicle in connection.vehicles:
            print(vehicle)
            exit()

    if args['-i']:
        vehicle = connection.vehicle(args['-i'])
    else:
        vehicle = next(connection.vehicles)

    if not vehicle:
        exit('Vehicle not found')

    if args['status']:
        print_vehicle(vehicle, args['-g'])
    elif args['print']:
        attr = args['<attribute>']
        if attr:
            if not attr in vehicle.data:
                exit('unknown attribute')
            print(vehicle.data[attr])
        else:
            def serialize(obj):
                if isinstance(obj, datetime):
                    return obj.isoformat()
            print(json.dumps(OrderedDict(sorted(vehicle.data.items())), indent=2, default=serialize))
    elif args['heater']:
        if args['start']:
            vehicle.start_heater()
        else:
            vehicle.stop_heater()
    elif args['lock']:
        vehicle.lock()
    elif args['unlock']:
        vehicle.unlock()
    elif args['call']:
        vehicle.call(args['<method>'])


if __name__ == '__main__':
   main()
