#!/usr/bin/env python

import json

from collections import OrderedDict

from twisted.internet import reactor
from twisted.internet import defer

from obstructx import db_introspect
from obstructx import db_pool
from obstructx import log

logger = log.get_logger()
logger.error("TEST")

class DbMethods(object):
    def extract_first(self, results):
        return [result[0] for result in results]

    def query_first(self, query, queryargs=None):
        if queryargs is None:
            queryargs = ()
        df = self.pool.runQuery(query, queryargs)
        df.addCallback(lambda x: x[0])
        return df

class Inquisitor(DbMethods):
    data = {'localhost':{5432:{}}}

    def initialize_pool(self, database):
        logger.error("initialize_pool")

        Inquisitor.data['localhost'][5432][database] = {}
        self.pool = db_pool.Pool(database)
        df = self.pool.start()
        return df

    def get_database_metadata(self, database):
        df = self.initialize_pool(database)
        df.addCallback(self.get_tables)
        return df

    def get_tables(self, *args):
        logger.error("get_tables")
        query = db_introspect.queries["list_tables"]
        df = self.pool.runQuery(query)
        df.addCallback(self.parse_tables)
        return df

    def parse_tables(self, tables):
        dfs = []
        for table in tables:
            database = table.table_catalog
            table = table.table_name
            Inquisitor.data['localhost'][5432][database][table] = {"fields":OrderedDict(), "indices":OrderedDict()}
            df = self.get_columns(table)
            df.addCallback(self.show_columns)
            df.addCallback(self.get_foreign_keys)
            df.addCallback(self.get_indices)
            df.addCallback(self.parse_indices)
            dfs.append(df)

        dfl = defer.DeferredList(dfs)
        #dfl.addCallback(self.get_foreign_keys)
        #dfl.addCallback(self.parse_foreign_keys)
        return dfl


    def get_databases(self, *args):
        logger.error("get_databses")
        query = db_introspect.queries["list_databses"]
        df = self.pool.runQuery(query)
        df.addCallback(self.extract_first)
        return df

    def get_columns(self, table, *args):
        logger.error("get_columns")
        query = db_introspect.queries["list_table_columns"]
        return self.pool.runQuery(query, (table,))

    def get_indices(self, table, *args):
        logger.error("get_indices: %s" % (table,))
        query = db_introspect.queries["list_table_indices"]
        df = self.pool.runQuery(query, (table,))
        return df

    def parse_indices(self, results):
        #print("parse_indices: %s" % results,)
        for result in results:
            leader = result.column_names[0]
            database_name = "booktown"
            Inquisitor.data['localhost'][5432][database_name][result.table_name]["fields"][leader]["leads_index"] = True

    def get_foreign_keys(self, table, *args):
        logger.error("get_foreign_keys")
        query = db_introspect.queries["list_foreign_keys"]
        df = self.pool.runQuery(query, (table,))
        df.addCallback(self.parse_foreign_keys, table)
        return df

    def parse_foreign_keys(self, results, table_name):
        for result in results:
            Inquisitor.data['localhost'][5432][result.database_name][result.table_name]["fields"][result.column_name]["references_foreign_key"] = (result.foreign_table_name, result.foreign_column_name,)
            Inquisitor.data['localhost'][5432][result.database_name][result.foreign_table_name]["fields"][result.foreign_column_name]["referenced_by_foreign_key"] = (result.table_name, result.column_name,)
        return table_name

    def show_result(self, result):
        if isinstance(result, basestring):
            print("RESULT: %s" % (result,))
            return
        for item in result:
            print("-- %s" % (item,))

    def show_columns(self, results):
        database = results[0].table_catalog
        table    = results[0].table_name
        nullable = {"YES":True, "NO":False}
        for column in results:
            val = {}
            val['name'] = column.column_name
            val['type'] = column.data_type
            val['nullable'] = nullable[column.is_nullable]
            val['default'] = column.column_default
            val['references_foreign_key'] = None
            val['referenced_by_foreign_key'] = None
            val['leads_index'] = False
            Inquisitor.data['localhost'][5432][database][table]["fields"][column.column_name] = val

        return table


@@ -653,30 +653,92 @@
  = %7B
-'localhost':%7B5432:%7B%7D%7D%7D
+%7D%0A%0A    def __init__(self, database_name):%0A        self.database_name = database_name
 %0A%0A  
@@ -759,34 +759,24 @@
 ze_pool(self
-, database
 ):%0A        l
@@ -835,35 +835,21 @@
 ata%5B
-'localhost'%5D%5B5432%5D%5B
+self.
 database
 %5D = 
@@ -844,16 +844,21 @@
 database
+_name
 %5D = %7B%7D%0A 
@@ -885,32 +885,37 @@
 b_pool.Pool(
+self.
 database
 )%0A        df
@@ -894,32 +894,37 @@
 ol(self.database
+_name
 )%0A        df = s
@@ -993,26 +993,16 @@
 ata(self
-, database
 ):%0A     
@@ -1030,24 +1030,16 @@
 ze_pool(
-database
 )%0A      
@@ -1502,35 +1502,16 @@
 or.data%5B
-'localhost'%5D%5B5432%5D%5B
 database
@@ -2799,82 +2799,29 @@
     
-database_name = %22booktown%22%0A            Inquisitor.data%5B'localhost'%5D%5B5432%5D%5B
+Inquisitor.data%5Bself.
 data
@@ -3274,35 +3274,16 @@
 or.data%5B
-'localhost'%5D%5B5432%5D%5B
 result.d
@@ -3458,35 +3458,16 @@
 or.data%5B
-'localhost'%5D%5B5432%5D%5B
 result.d
@@ -3904,16 +3904,21 @@
 database
+_name
  = resul
@@ -3951,19 +3951,16 @@
   table 
-   
 = result
@@ -4441,35 +4441,16 @@
 ata%5B
-'localhost'%5D%5B5432%5D%5B
 database
 %5D%5Bta
@@ -4437,32 +4437,37 @@
 or.data%5Bdatabase
+_name
 %5D%5Btable%5D%5B%22fields

Add a 'database_name' attribute. Remove hostname and port from json structure