import couchdb
import requests
import json

def allDb(server):
    #print(dir(server))
    #print(list(server))
    return [
        server[dbname]
        for dbname in list(server)
        if not '_' in dbname[:1]
        #if dbname == 'test'
    ]

def allDoc(db):
    return [
        {
            '_id':result.id, 
            '_rev':result['value']['rev']
        }
        for result in db.view('_all_docs')
        if not '_design/' in result.id
    ]

def haveTrashCertificate(db):
    #contain a dodcument whose id is "trash"
    if db.get('trash'):
        trash=True
    else:
        trash=False
    return trash

def wipeDb(db):
    for key in allDoc(db):
        #print(key)
        db.delete(key)
    db.compact()

########################################

def CmdRestGetFromView(view):
     response = requests.get(view)
     if response.status_code in [200]:
         result = response.json()
         for row in result['rows']:
            yield (row['key'],row['value'])
 
def CmdRestPutFromView(doc):
    rest=doc['rest']
    auth = rest['auth'] if 'auth' in rest else None
    headers = {'content-type': 'application/json'}
    ret = []
    if 'view' in rest:
        #expect complete database url
        for url,payload in CmdRestGetFromView(rest['view']):
             response = requests.put(url,data=json.dumps(payload),headers=headers,auth=auth)
             if response.status_code in [201,200]:
                try:
                    ret.append(response.json())
                except:
                    ret.append(response.text)
             else:
                ret.append(response.reason)
    return ret

def CmdRestPostFromView(doc):
    rest=doc['rest']
    auth = rest['auth'] if 'auth' in rest else None
    headers = {'content-type': 'application/json'}
    ret = []
    if 'view' in rest:
        #expect complete database url
        for url,payload in CmdRestGetFromView(rest['view']):
             response = requests.post(url,data=json.dumps(payload),headers=headers,auth=auth)
             if response.status_code in [201,200]:
                try:
                    ret.append(response.json())
                except:
                    ret.append(response.text)
             else:
                ret.append(response.reason)
    return ret

def CmdRest(cmddb):
    for key in allDoc(cmddb):
        doc = cmddb.get(key['_id'])
        if 'rest' in doc and not 'response' in doc:
            if doc['rest']['method'] == 'PUT':
                if 'view' in doc['rest']:
                    response = CmdRestPutFromView(doc)
                    doc['response'] = response
                    cmddb.put(doc)
            elif doc['rest']['method'] == 'POST':
                if 'view' in doc['rest']:
                    response = CmdRestPostFromView(doc)
                    doc['response'] = response
                    cmddb.save(doc)
            elif doc['rest']['method'] == 'GET':
                if 'view' in doc['rest']:
                    view = doc['rest']['view']
                    response=list(CmdRestGetFromView(view))
                    doc['response'] = response
                    cmddb.save(doc)

def CmdMaintainDesignDoc(cmddb):
    '''
    will make sure design doc never disapear event if we trash the databse and recreate it
    will make sure design doc stay consistant whereever i edit it
    '''
    pass

def CmdManageDb(cmddb):
    '''
    can create and delete a databse
    backup and restore it
    even make sure designdoc are in place
    support replication and continuous replication , one sided and two sided
    use filtered replication
    '''
    pass
    '''
    {
        'db' : {
            'name' : "name of the db",
            'from' : "optional creation time filtered replication",
            'sync' : "optional continuous filtered replication",
            'backup' : "yes if you want a snapshop in attachment, can write restore with date and it will restore",
            'log' : "dont touch, just read it",
            "delete" : "it will make sure it stay deleted",
            "compact" : "it will compact the database",
            "wipe" :  "it will trigger databse wipe"
        }
    }
    list of these would be awesome
    '''

########################################

def BusinessRuleWipeCertificate(server):
    for db in allDb(server):
        if haveTrashCertificate(db):
            print("wipe %s"%db.name)
            wipeDb(db)

_cmddbname = "couchguy"
def BusinessRuleMaintainCommandDb(server):
    if not _cmddbname in server:
        server.create(_cmddbname)
    cmddb = server[_cmddbname]
    CmdRest(cmddb)
    #more todo

def BusinnessRuleBackup(server):
    '''
    the ability to save a snapshot from database
    '''
    pass

def BusinnessRule(server):
    pass

if __name__ == '__main__':
    server = couchdb.Server('http://tool.media5corp.com:5984/')
    for businessLogic in [BusinessRuleWipeCertificate,
                          BusinessRuleMaintainCommandDb]:
        businessLogic(server)

