"""
Refactored helper methods for working with the database. This is a work in
progress. You should probably be looking at ui.voyager until this work is
more fully developed.
"""

import re
import pymarc
import logging

from PyZ3950 import zoom
from django.db import connections
from django.conf import settings

# oracle specific configuration since Voyager's Oracle requires ASCII

if settings.DATABASES['voyager']['ENGINE'] == 'django.db.backends.oracle':
    import django.utils.encoding
    import django.db.backends.oracle.base
    # connections are in ascii
    django.db.backends.oracle.base._setup_environment([
        ('NLS_LANG', '.US7ASCII'),
    ])
    # string bind parameters must not be promoted to Unicode in order to use
    # Voyager's antiquated Oracle indexes properly
    # https://github.com/gwu-libraries/launchpad/issues/611
    django.db.backends.oracle.base.convert_unicode = \
        django.utils.encoding.force_bytes


def get_item(bibid):
    """
    Get JSON-LD for a given bibid.
    """
    item = {
        '@type': 'Book',
    }

    marc = get_marc(bibid)

    item['wrlc'] = bibid

    # get item name (title)
    item['name'] = marc['245']['a'].strip(' /')

    # get oclc number
    for f in marc.get_fields('035'):
        if f['a'] and f['a'].startswith('(OCoLC)'):
            if 'oclc' not in item:
                item['oclc'] = []
            oclc = f['a'].replace('(OCoLC)', '').replace('OCM', '')
            item['oclc'].append(oclc)

    # get lccn
    f = marc['010']
    if f:
        item['lccn'] = marc['010']['a'].strip()

    # get isbns
    for f in marc.get_fields('020'):
        if 'isbn' not in item:
            item['isbn'] = []
        isbn = f['a']
        # extract just the isbn, e.g. "0801883814 (hardcover : alk. paper)"
        isbn = isbn.split()[0]
        item['isbn'].append(isbn)

    # get issns
    for f in marc.get_fields('022'):
        if 'issn' not in item:
            item['issn'] = []
        item['issn'].append(f['a'])

    return item


def get_marc(bibid):
    """
    Get pymarc.Record for a given bibid.
    """
    query = "SELECT wrlcdb.getBibBlob(%s) AS marcblob from bib_master"
    cursor = connections['voyager'].cursor()
    cursor.execute(query, [bibid])
    row = cursor.fetchone()
    raw_marc = str(row[0])
    record = pymarc.record.Record(data=raw_marc)
    return record


def get_availability(bibid):
    """
    Get availability information as JSON-LD for a given bibid.
    """
    if not isinstance(bibid, basestring):
        raise Exception("supplied a non-string: %s" % bibid)

    url = 'http://%s/item/%s' % (_get_hostname(), bibid)
    results = {
        '@context': {
            '@vocab': 'http://schema.org/',
        },
        '@id': url,
        'offers': [],
        'wrlc': bibid,
    }

    # if the bibid is numeric we can look it up locally in Voyager
    if re.match('^\d+$', bibid):
        results['offers'] = _get_offers(bibid)

    # George Mason and Georgetown have special ids in Summon and we need
    # to talk to their catalogs to determine availability
    else:
        if bibid.startswith('m'):
            results['offers'] = _get_offers_z3950(bibid, 'George Mason')
        elif bibid.startswith('b'):
            results['offers'] = _get_offers_z3950(bibid, 'Georgetown')
        else:
            raise Exception("unknown bibid format %s" % bibid)

        # update wrlc id if there is a record in voyager for it
        wrlc_id = get_bibid_from_summonid(bibid)
        if wrlc_id:
            results['wrlc'] = wrlc_id
            results['summon'] = bibid

    return results


def get_bibid_from_summonid(id):
    """
    For some reason Georgetown and GeorgeMason loaded Summon with their
    own IDs so we need to look them up differently.
    """
    if re.match('^\d+$', id):
        return id
    if id.startswith('b'):
        return get_bibid_from_gtid(id)
    elif id.startswith('m'):
        return get_bibid_from_gmid(id)
    else:
        return None


def get_bibid_from_gtid(id):
    query = \
        """
        SELECT bib_index.bib_id
        FROM bib_index, bib_master