#!/usr/bin/env python
"""
Console-based access to the Gatherer Magic Card Database.

Usage: %prog [options] [cardname]
"""

import sys
import argparse

from mtglib import __version__
from mtglib.gatherer_request import SearchRequest
from mtglib.card_extractor import CardExtractor
from mtglib.card_renderer import CardList
from mtglib.constants import separator, readme, random_url


def main():
    parser = argparse.ArgumentParser(description='Search for magic cards')
    search = parser.add_argument_group('search', 'Card search options')
    display = parser.add_argument_group('display', 'Display options')

    search.add_argument('-t', '--text',
                        help='containing rules text TEXT', metavar='TEXT')
    search.add_argument('--color', help='cards matching COLOR.  Supports one-letter abbreviations (w, u, b, r, g), guilds/shards (e.g. boros, esper), and colorless (c).')
    search.add_argument('--type', help='cards matching TYPE or SUBTYPE (e.g. artifact, creature, legendary, snow, goblin, forest, plane)')
    search.add_argument('--power',
                        help='cards with power POWER (uses <, >, =)')
    search.add_argument('--tough',
                        help='cards with toughness TOUGHNESS (uses <, >, =)')
    search.add_argument('--block',
                        help='cards from block BLOCK')
    search.add_argument('--format',
                        help='cards from format FORMAT')
    search.add_argument('--set',
                        help='cards matching expansion set SET (e.g. unlimited, mirrodin, or official abbreviations such as RTR or WWK)')
    search.add_argument('--rarity',
                        help='cards matching rarity RARITY (c, u, r, m)')
    search.add_argument('--cmc', help='cards with converted mana '
                        'cost CMC (uses <, >, =)')
    display.add_argument('-r', '--reminder', action='store_true',
                         help='show reminder text')
    display.add_argument('--exact', action='store_true',
                         help='cards must match the name exactly (e.g. "fork" will not match "forked bolt")')
    display.add_argument('--hidesets', action='store_true',
                        help='hide which sets the card was printed in')
    display.add_argument('--rulings', action='store_true',
                        help='show rulings for the card')
    search.add_argument('--special', action='store_true',
                        help='include special cards in search (e.g. planes, schemes)')
    display.add_argument('--flavor', action='store_true',
                        help='show flavor text')
    search.add_argument('-xc', '--exclude-other-colors', action='store_true',
                        help='exclude colors not explicity specified')
    search.add_argument('-xt', '--exclude-other-types', action='store_true',
                        help='exclude types not explicity specified')
    display.add_argument('--json', action='store_true',
                        help='output card in JSON format')
    search.add_argument('name', nargs='*', help='name of card (optional)')
    parser.add_argument('--version', action='version', version=__version__)
    parser.add_argument('--random', action='store_true', help='display a card selected at random')

    args = parser.parse_args()
    if args.name and args.exact:
        args.name = 'm/^{}$/'.format('\s'.join(args.name))
    elif args.name:
        args.name =  ','.join(args.name)
    elif args.exact and not args.name:
        parser.error('Cannot require exact name if no name given in search query.\n'
                     '--exact must be used with name arguments.')
    if not (args.text or args.color or args.type or args.power or args.tough
            or args.block or args.set or args.rarity or args.cmc or args.name
            or args.random or args.format):
        parser.error('Require at least one search option or card name.  '
                     'Type "mtg --help" for more information.')
    exclude_others = set()
    if args.exclude_other_colors:
        if not args.color:
            parser.error('Cannot exclude other colors if no color given in search query.\n'
                         '--exclude-other-colors or -xc must be used with --color')
        exclude_others.add('color')
    if args.exclude_other_types:
        if not args.type:
            parser.error('Cannot exclude other types if no type given in search query.\n'
                         '--exclude-other-types or -xt must be used with --type')
        exclude_others.add('type')


    if args.random:
        url = random_url
    else:
        request = SearchRequest(vars(args), special=args.special,
                                exclude_others=exclude_others)
        try:
            url = request.url
        except ValueError as e:
            print('Problem with input: {}\nTry "mtg --help" for assistance.'.format(e))
            return 0


    try:
        cards = CardExtractor(url).cards
    except KeyboardInterrupt:
        return 0
    except SyntaxError as e:
        print('Could not parse options: {0}'.format(e.msg))
        return 0

    cardlist = CardList(cards, rulings=args.rulings, reminders=args.reminder,
                        flavor=args.flavor, printings=not args.hidesets, json=args.json)
    for line in cardlist.render(): print(line)
    return 0

if __name__ == '__main__':
    sys.exit(main())