#! /usr/bin/env python

import psutil # Used to determine available RAM
import sys
import gc
import os
import re
import csv
import json
import codecs
import logging
from datetime import datetime, timedelta
from decimal import Decimal

from django.core.management.base import BaseCommand, CommandError
from django.core.exceptions import ObjectDoesNotExist
from django.db import transaction
from django.db import connection, reset_queries

from django.db.models import Max

from logos.settings import BIBLES_DIR, DATABASES

from bibleapp.models import BibleTranslations, BibleBooks, BibleVerses, \
    BibleConcordance, BibleDict, XRefs

from _booktbl import book_table, xref_books
from logos.constants import PUNCTUATION, STOP_WORDS
from logos.utils import *

from django.conf import settings
logger = logging.getLogger(__name__)
logging.config.dictConfig(settings.LOGGING)

class Command(BaseCommand):
    help = 'Import the translations'

    def add_arguments(self, parser):

        # Named (optional) arguments
        parser.add_argument('--xrefs',
            action='store_true',
            default=False,
            help="Import cross-references.txt file into database")

        parser.add_argument('--list-translations',
            action='store_true',
            default = False,
            help="List all translations in database")

        parser.add_argument('--remove-translation',
            action='store',
            help="Purge translation from database")

        parser.add_argument('--replace-version',
            action='store',
            help="Only replace the specified translation in the" + \
            "database.  Should be a folder name in bibles/")

        parser.add_argument('--use-more-ram',
            action='store_true',
            default=False,
            help="Try to speed up a sqlite3 database import by " + \
                "storing the journal in ram")

        parser.add_argument('--import',
            action='store_true',
            default=False,
            help="Import the database to original plain text files")

        parser.add_argument('--export',
            action='store_true',
            default=False,
            help="Export the database to original plain text files")

    def handle(self, *args, **options):
        logger.debug ("args = "+str(args))
        logger.debug ("options = "+ str(options))

        if options['xrefs']:
            import_xrefs()
            return

        if options['export']:
            dump_db()
            return

        if options['list_translations']:
            trans = [tr.name for tr in BibleTranslations.objects.all()]
            sys.stdout.write("Loaded Translations: {}\n".format(", ".join(trans)))
            return

        if options['remove_translation']:
            trans = options['remove_translation']
            result = purge_translation(trans)
            if result == False:
                print "Could not find translation {}".format(trans)
            else:
                print "Translation {} removed from database".format(trans)
            return

        if options['use_more_ram'] and DATABASES['bibles']['ENGINE'].endswith('sqlite3'):
            logger.info("Allocating the SQLITE3 journal in RAM")
            vm = psutil.virtual_memory()
            cursor = connection.cursor()
            cursor.execute("PRAGMA Journal_mode = MEMORY")
            cursor.execute("PRAGMA Page_size")
            row = cursor.fetchone()
            page_size = row[0]
            # use 75% of available memory for cache
            cache_size = int(.75 * vm.available / page_size)
            cursor.execute("PRAGMA Cache_Size = "+str(cache_size))
            print "page_size = " + str(page_size) + " bytes"
            print "cache_size = " + str(cache_size) + " pages"

        

        if options['import'] or options['replace_version']:
            if options['replace_version']:
                version = options['replace_version']
                biblepath = BIBLES_DIR + os.sep + version        
                if not os.path.exists(biblepath):
                    print "Version %s does not exists in bibles/" % (version,)
                    return
            else:
                # don't bother repopulating the strongs tables if we are just
                # replacing a single translation
                try:
                    import_strongs_tables() 
                except IOError:
                    # If dict folder doesn't exist then just carry on
                    pass
            import_trans(options)
            import_concordance(options)
        else:
            print "Nothing to do"

def dump_db():
    biblepath = settings.BIBLES_DIR 
    for trans in BibleTranslations.objects.all():
        vers_path = os.path.join(biblepath, trans.name)
            
        if not os.path.exists(vers_path):
            print vers_path
            os.mkdir(vers_path)
            for bk in trans.biblebooks_set.order_by('id'):
                filepath = os.path.join(vers_path, bk.canonical+".txt")
                f = codecs.open(filepath, 'wb', 'utf-8')
                for vs in bk.bibleverses_set.order_by('chapter','verse'):
                    f.write(u"{}:{} {}\n".format(vs.chapter, vs.verse, vs.verse_text))
                
                f.close()
        else:
            print "skipping " + trans.name + " (already exists)"

def import_xrefs():