# -*- coding: utf-8 -*-
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements.  See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership.  The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License.  You may obtain a copy of the License at
#
#   http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied.  See the License for the
# specific language governing permissions and limitations
# under the License.

try:
    import json
    import os
    import types

    from config import config_fields
except ImportError, e:
    import sys
    print "ImportError", e
    sys.exit(1)


def getvalue(dictionary, key):
    if key in dictionary:
        return dictionary[key]
    else:
        return None


def splitcsvstring(string):
    if string is not None:
        return filter(lambda x: x.strip() != '', string.split(','))
    else:
        return []


def splitverbsubject(string):
    idx = 0
    for char in string:
        if char.islower():
            idx += 1
        else:
            break
    return string[:idx].lower(), string[idx:].lower()


def savecache(apicache, json_file):
    """
    Saves apicache dictionary as json_file, returns dictionary as indented str
    """
    if apicache is None or apicache is {}:
        return ""
    apicachestr = json.dumps(apicache, indent=2)
    with open(json_file, 'w') as cache_file:
        cache_file.write(apicachestr)
    return apicachestr


def loadcache(json_file):
    """
    Loads json file as dictionary, feeds it to monkeycache and spits result
    """
    f = open(json_file, 'r')
    data = f.read()
    f.close()
    try:
        apicache = json.loads(data)
    except ValueError, e:
        print "Error processing json:", json_file, e
        return {}
    return apicache


def monkeycache(apis):
    """
    Feed this a dictionary of api bananas, it spits out processed cache
    """
    if isinstance(type(apis), types.NoneType) or apis is None:
        return {}

    responsekey = filter(lambda x: 'response' in x, apis.keys())

    if len(responsekey) == 0:
        print "[monkeycache] Invalid dictionary, has no response"
        return None
    if len(responsekey) != 1:
        print "[monkeycache] Multiple responsekeys, chosing first one"

    responsekey = responsekey[0]
    verbs = set()
    cache = {}
    cache['count'] = getvalue(apis[responsekey], 'count')
    cache['asyncapis'] = []

    apilist = getvalue(apis[responsekey], 'api')
    if apilist is None:
        print "[monkeycache] Server response issue, no apis found"

    for api in apilist:
        name = getvalue(api, 'name')
        verb, subject = splitverbsubject(name)

        apidict = {}
        apidict['name'] = name
        apidict['description'] = getvalue(api, 'description')
        apidict['isasync'] = getvalue(api, 'isasync')
        if apidict['isasync']:
            cache['asyncapis'].append(name)
        apidict['related'] = splitcsvstring(getvalue(api, 'related'))

        required = []
        apiparams = []
        for param in getvalue(api, 'params'):
            apiparam = {}
            apiparam['name'] = getvalue(param, 'name')
            apiparam['description'] = getvalue(param, 'description')
            apiparam['required'] = (getvalue(param, 'required') is True)
            apiparam['length'] = int(getvalue(param, 'length'))
            apiparam['type'] = getvalue(param, 'type')
            apiparam['related'] = splitcsvstring(getvalue(param, 'related'))
            if apiparam['required']:
                required.append(apiparam['name'])
            apiparams.append(apiparam)

        apidict['requiredparams'] = required
        apidict['params'] = apiparams
        if verb not in cache:
            cache[verb] = {}
        cache[verb][subject] = apidict
        verbs.add(verb)

    cache['verbs'] = list(verbs)
    return cache


def main(json_file):
    """
    cachemaker.py creates a precache datastore of all available apis of
    CloudStack and dumps the precache dictionary in an
    importable python module. This way we cheat on the runtime overhead of
    completing commands and help docs. This reduces the overall search and
    cache_miss (computation) complexity from O(n) to O(1) for any valid cmd.
    """
    f = open("precache.py", "w")
    f.write("""# -*- coding: utf-8 -*-
# Auto-generated code by cachemaker.py
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements.  See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership.  The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License.  You may obtain a copy of the License at
#
#   http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied.  See the License for the
# specific language governing permissions and limitations
# under the License.""")
    f.write("\napicache = %s" % loadcache(json_file))
    f.close()

if __name__ == "__main__":
    cache_file = config_fields['core']['cache_file']
    print "[cachemaker] Pre-caching using user's cloudmonkey cache", cache_file
    if os.path.exists(cache_file):
        main(cache_file)
    else:
        print "[cachemaker] Unable to cache apis, file not found", cache_file
        print "[cachemaker] Run cloudmonkey sync to generate cache"
