"""
Code for handling the ENGAGE_DJANGO_COMPONENTS setting.
"""
import json
import os.path

from errors import ValidationError

valid_component_names = [ "celery", "memcached", "mysql", "redis", ]
additional_requirements = { 
    'celery' : [ 'django-celery' ],
    'memcached' : [ 'python-memcached' ],
    'redis' : [ 'redis' ]
}

COMPONENTS_FILENAME = "engage_components.json"

def read_components_file(fileobj, filepath, django_config_components=None):
    """Read the components file from the opened fileobj (could be a real file
    or a pseudo-file in an archive). Parse the json, validate the components,
    and return the list. If django_config_components is provided (from the
    django_config file), compare and make sure they match.
    """
    # we only include last component of filepath in error messages, as we are usually
    # installing to a temp dir
    filepath = os.path.join(os.path.basename(os.path.dirname(filepath)), os.path.basename(filepath))
    try:
        data = json.loads(fileobj.read())
    except Exception, e:
        raise ValidationError("Error in JSON parse of file %s: %s" % (filepath, str(e)))
    if not isinstance(data, list):
        raise ValidationError("Additional components file %s does not contain a list of components" % filepath)
    component_list = [unicode.lower(s) for s in data]
    bad_comps = []
    for comp in component_list:
        if comp not in valid_component_names:
            bad_comps.append(comp)
    if len(bad_comps)>0:
        raise ValidationError("Additional components file %s contains invalid components %s" % (filepath, bad_comps))
    if django_config_components:
        missmatch = False
        if len(django_config_components)!=len(component_list) or \
               set(django_config_components)!=set(component_list):
            raise ValidationError("Component list in file %s (%s) does not match component list generated by packager (%s). Perhaps you need to rerun the packager." %
                                  (filepath, component_list, django_config_components))
    return component_list


def get_additional_requirements(component):
    try:
        return additional_requirements[component]
    except:
        return []

def get_resource_specs(component_list, host_id, host_key):
    specs = []
    component_list = [unicode.lower(s) for s in component_list]
    if u"celery" in component_list:
        specs.append({"id":"rabbitmq-1", "key":{"name":"rabbitmq", "version":"2.4"},
                      "inside":{"id":host_id, "key":host_key,
                                "port_mapping": {"host":"host"}}
                     })
        specs.append({"id":"celery-1", "key":{"name":"Celery", "version":"2.3"},
                      "inside":{"id":host_id, "key":host_key,
                                "port_mapping": {"host":"host"}}
                     })
        specs.append({"id":"celery-django-1", "key":{"name":"celery-django-adapter", "version":"any"},
                      "inside":{"id":host_id, "key":host_key,
                                "port_mapping": {"host":"host"}}
                     })
        specs.append({"id":"celery-django-worker-1", "key":{"name":"celery-django-worker", "version":"1.0"},
                      "inside":{"id":host_id, "key":host_key,
                                "port_mapping": {"host":"host"}}
                     })
        specs.append({"id":"celerybeat-django-worker-1", "key":{"name":"celerybeat-django-worker", "version":"1.0"},
                      "inside":{"id":host_id, "key":host_key,
                                "port_mapping": {"host":"host"}}
                     })
    else:
        specs.append({"id":"dummy-celery-1", "key":{"name":"django-dummy-celery-adapter", "version":"any"},
                      "inside":{"id":host_id, "key":host_key,
                                "port_mapping": {"host":"host"}}})
    if u"memcached" in component_list:
        specs.append({"id":"memcache-1", "key":{"name":"memcached-django-adapter", "version":"any"},
                      "inside":{"id":host_id, "key":host_key,
                                "port_mapping": {"host":"host"}}})
    else:
        specs.append({"id":"dummycache-1", "key":{"name":"django-dummy-cache-adapter", "version":"any"},
                   "inside":{"id":host_id, "key":host_key,
                             "port_mapping": {"host":"host"}}})
    if u"redis" in component_list:
        specs.append({"id":"redis-1", "key":{"name":"redis", "version":"2.2"},
                      "inside":{"id":host_id, "key":host_key,
                                "port_mapping": {"host":"host"}}})
    if u"mysql" in component_list:
        if host_key['name']=='mac-osx':
            specs.append({"id":"mysql-server", "key":{"name":"mysql-macports",
                                                      "version":"5.1"},
                          "inside":{"id":host_id, "key":host_key,
                                    "port_mapping": {"host":"host"}}})
        else:
            specs.append({"id":"mysql-server", "key":{"name":"mysql-apt",
                                                      "version":"5.1"},
                          "inside":{"id":host_id, "key":host_key,
                                    "port_mapping": {"host":"host"}}})
        specs.append({"id":"mysql-connector", "key":{"name":"mysql-connector-for-django", "version":"5.1"},
                      "inside":{"id":host_id, "key":host_key,
                                "port_mapping": {"host":"host"}}})
    else:
        specs.append({"id":"sqlite-connector", "key":{"name":"sqlite-connector-for-django", "version":"1.0"},
                      "inside":{"id":host_id, "key":host_key,
                                "port_mapping": {"host":"host"}}})
    return specs

def get_additional_config_props(component_list, host_id, host_key):
    props = []
    component_list = [unicode.lower(s) for s in component_list]
    if "memcached" in component_list:
        pass # no additional properties
    if "mysql" in component_list:
        props.append({"resource": "mysql-server", "name": "mysql_admin_password",
                      "type":"password", "description":"Password for MySQL root user",
                      "default":None, "optional":None})
        props.append({"resource": "mysql-connector", "name": "PASSWORD",
                      "type":"password", "description":"MySQL django user password",
                      "default":None, "optional":None})
        
    return props

