#!/usr/bin/env python
# -*- coding: utf-8

import os
import sys
import argparse

import anvio.db as db
import anvio.dbops as dbops
import anvio.dictio as dictio
import anvio.terminal as terminal 

from anvio.errors import ConfigError


run = terminal.Run()
progress = terminal.Progress()


def update_profile_db_from_v14_to_v15(profile_db_path, just_do_it = False, skip_runinfo = False):
    if profile_db_path is None:
        raise ConfigError, "No profile database is given."

    # make sure someone is not being funny
    dbops.is_profile_db(profile_db_path)

    # make sure the version is 5
    profile_db = db.DB(profile_db_path, None, ignore_version = True)
    if str(profile_db.get_version()) != '14':
        raise ConfigError, "Version of this profile database is not 14 (hence, this script cannot really do anything)."

    is_merged = profile_db.get_meta_value('merged')

    if not just_do_it:
        try:
            run.warning('This script will try to upgrade your profile database. If things go south, you will end up having to\
                         re-profile your data :/ It may be a good idea to back it up first. If you already backed your stuff\
                         or you are certain that it will work, or if you are a lucky person in general, press ENTER to continue.\
                         If you want to cancel the upgrade, press CTRL+C now. If you want to avoid this message the next time,\
                         use "--just-do-it" flag.')
            raw_input("Press ENTER to continue...\n")
        except:
            print
            sys.exit()

    progress.new("Trying to upgrade the %s profile database" % 'merged' if is_merged else 'single')

    # update the runinfo.cp
    input_dir = os.path.dirname(os.path.abspath(profile_db_path))
    P = lambda x: os.path.join(input_dir, x)
    E = lambda x: os.path.exists(x)
    
    runinfo_path = P('RUNINFO.cp') if E(P('RUNINFO.cp')) else None
    runinfo_path = P('RUNINFO.mcp') if E(P('RUNINFO.mcp')) else None

    if not skip_runinfo:
        if not runinfo_path:
            raise ConfigError, "I can't find the runinfo file around this profile :("

        runinfo = dictio.read_serialized_object(runinfo_path)
        if not runinfo.has_key('blank'):
            runinfo['blank'] = False

            dictio.write_serialized_object(runinfo, runinfo_path)

    # add the new value
    profile_db.set_meta_value('blank', False)

    # set the version
    profile_db.remove_meta_key_value_pair('version')
    profile_db.set_version('15')

    # bye
    profile_db.disconnect()
    progress.end()

    run.info_single("Database successfully upgraded to version 15!")


if __name__ == '__main__':
    parser = argparse.ArgumentParser(description='A simple script to upgrade profile database to from version 14 version 15')

    parser.add_argument('profile_db', metavar = 'PROFILE_DB', help = 'Profile database (of version 14)')
    parser.add_argument('--just-do-it', default=False, action="store_true", help = "Do not bother me with warnings")
    parser.add_argument('--skip-runinfo', default=False, action="store_true", help = "Do not bother trying to upgrade the runinfo file")

    args = parser.parse_args()

    try:
        update_profile_db_from_v14_to_v15(args.profile_db, just_do_it = args.just_do_it, skip_runinfo = args.skip_runinfo)
    except ConfigError, e:
        print e
        sys.exit(-1)
