#!/home/petli/cod/bin/python
# Hey Emacs, this is -*-python-*-
#
# Copyright 2013 Peter Liljenberg <peter.liljenberg@gmail.com>
#
# Distributed under an MIT license, please see LICENSE in the top dir.

import sys
import os
import argparse
import subprocess
import shutil

from pkg_resources import resource_filename

from codplayer import db, model
from codplayer import serialize

def cmd_init(args):
    try:
        db.Database.init_db(args.db_dir)
    except db.DatabaseError, e:
        sys.exit(str(e))


def cmd_config(args):
    dest_dir = args.config_dir or ''
    for f in ('codplayer.conf', 'codrest.conf'):
        src = resource_filename('codplayer', 'data/config/' + f)
        dest = os.path.join(dest_dir, f)
        if os.path.exists(dest) and not args.force:
            sys.exit('file already exists (use -f to overwrite): {0}'.format(dest))

        sys.stderr.write('creating {0}\n'.format(dest))
        shutil.copyfile(src, dest)


def cmd_list(args):
    try:
        d = db.Database(args.db_dir)
        
        for db_id in d.iterdiscs_db_ids():
            try:
                disc = d.get_disc_by_db_id(db_id)
                if disc:
                    sys.stdout.write('{0} {1:2d} tracks {2}/{3}\n'.format(
                            db_id, len(disc.tracks),
                            disc.artist.encode('utf-8') if disc.artist else '?',
                            disc.title.encode('utf-8') if disc.title else '?'
                            ))
            except model.DiscInfoError, e:
                sys.stderr.write('error reading {0}: {1}\n'.format(db_id, e))
            
    except db.DatabaseError, e:
        sys.exit(str(e))


def cmd_ls_discs(args):
    try:
        d = db.Database(args.db_dir)

        dirs = ["ls", "-lh"]
        for db_id in args.ids:
            if db.Database.is_valid_disc_id(db_id):
                dirs.append(d.get_disc_dir(db.Database.disc_to_db_id(db_id)))
            elif db.Database.is_valid_db_id(db_id):
                dirs.append(d.get_disc_dir(db_id))
            else:
                sys.exit('invalid disc ID: {0}'.format(db_id))

        sys.exit(subprocess.call(dirs))

    except db.DatabaseError, e:
        sys.exit(str(e))


def cmd_toc(args):
    try:
        d = db.Database(args.db_dir)

        if db.Database.is_valid_disc_id(args.id):
            db_id = db.Database.disc_to_db_id(args.id)
        elif db.Database.is_valid_db_id(args.id):
            db_id = args.id
        else:
            sys.exit('invalid disc ID: {0}'.format(args.id))

        with open(d.get_orig_toc_path(db_id), 'rt') as f:
            sys.stdout.writelines(f)

    except IOError, e:
        sys.exit(str(e))
    except db.DatabaseError, e:
        sys.exit(str(e))


def cmd_disc(args):
    try:
        d = db.Database(args.db_dir)

        if db.Database.is_valid_disc_id(args.id):
            disc = d.get_disc_by_disc_id(args.id)
        elif db.Database.is_valid_db_id(args.id):
            disc = d.get_disc_by_db_id(args.id)
        else:
            sys.exit('invalid disc ID: {0}'.format(args.id))

        sys.stdout.write(serialize.get_jsons(disc, pretty = True))
        sys.stdout.write('\n')

    except IOError, e:
        sys.exit(str(e))
    except db.DatabaseError, e:
        sys.exit(str(e))


#
# Set up the command argument parsing
#

parser = argparse.ArgumentParser(description = 'codplayer database administration')

subparsers = parser.add_subparsers(help = 'command')

parser_init = subparsers.add_parser(
    'init', help = 'initialise a database in an existing, empty directory')
parser_init.add_argument('db_dir')
parser_init.set_defaults(func = cmd_init)

parser_config = subparsers.add_parser(
    'config', help = 'create default config files in the current directory')
parser_config.add_argument('-f', '--force', action = 'store_true',
                           help = 'overwrite any existing files')
parser_config.add_argument('config_dir', nargs = '?',
                           help = 'create files here instead of current directory')
parser_config.set_defaults(func = cmd_config)

parser_list = subparsers.add_parser(
    'list', help = 'list the discs in a database')
parser_list.add_argument('db_dir')
parser_list.set_defaults(func = cmd_list)


parser_ls_disc = subparsers.add_parser(
    'ls', help = 'run ls -lh on disc dirs in a database')
parser_ls_disc.add_argument('db_dir', help = 'Path to database directory')
parser_ls_disc.add_argument('ids', nargs='+',
                            help = 'Musicbrainz or database disc IDs')
parser_ls_disc.set_defaults(func = cmd_ls_discs)


parser_toc = subparsers.add_parser(
    'toc', help = 'output the raw disc TOC generated by cdrdao')
parser_toc.add_argument('db_dir', help = 'Path to database directory')
parser_toc.add_argument('id', help = 'Musicbrainz or database disc ID')
parser_toc.set_defaults(func = cmd_toc)


parser_disc = subparsers.add_parser(
    'disc', help = 'output disc info as JSON')
parser_disc.add_argument('db_dir', help = 'Path to database directory')
parser_disc.add_argument('id', help = 'Musicbrainz or database disc ID')
parser_disc.set_defaults(func = cmd_disc)


if __name__ == '__main__':
    args = parser.parse_args()
    args.func(args)
    
