# -*- 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 cache_file
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 isinstance(type(apicache), types.NoneType) or 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'] = []

    for api in getvalue(apis[responsekey], 'api'):
        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__":
    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"
