/*
 * Copyright (C) 2008 The Android Open Source Project
 *
 * Licensed 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.
 */

#include <stdlib.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>

#define LOG_TAG "PropertyManager"

#include <cutils/log.h>

#include "PropertyManager.h"

PropertyManager::PropertyManager() {
    mNamespaces = new PropertyNamespaceCollection();
    pthread_mutex_init(&mLock, NULL);
}

PropertyManager::~PropertyManager() {
    PropertyNamespaceCollection::iterator it;

    for (it = mNamespaces->begin(); it != mNamespaces->end();) {
        delete (*it);
        it = mNamespaces->erase(it);
    }
    delete mNamespaces;
}

PropertyNamespace *PropertyManager::lookupNamespace_UNLOCKED(const char *ns) {
    PropertyNamespaceCollection::iterator ns_it;

    for (ns_it = mNamespaces->begin(); ns_it != mNamespaces->end(); ++ns_it) {
        if (!strcasecmp(ns, (*ns_it)->getName()))
            return (*ns_it);
    }
    errno = ENOENT;
    return NULL;
}

Property *PropertyManager::lookupProperty_UNLOCKED(PropertyNamespace *ns, const char *name) {
    PropertyCollection::iterator it;

    for (it = ns->getProperties()->begin();
         it != ns->getProperties()->end(); ++it) {
        if (!strcasecmp(name, (*it)->getName()))
            return (*it);
    }
    errno = ENOENT;
    return NULL;
}

int PropertyManager::attachProperty(const char *ns_name, Property *p) {
    PropertyNamespace *ns;

    ALOGD("Attaching property %s to namespace %s", p->getName(), ns_name);
    pthread_mutex_lock(&mLock);
    if (!(ns = lookupNamespace_UNLOCKED(ns_name))) {
        ALOGD("Creating namespace %s", ns_name);
        ns = new PropertyNamespace(ns_name);
        mNamespaces->push_back(ns);
    }

    if (lookupProperty_UNLOCKED(ns, p->getName())) {
        errno = EADDRINUSE;
        pthread_mutex_unlock(&mLock);
        ALOGE("Failed to register property %s.%s (%s)",
            ns_name, p->getName(), strerror(errno));
        return -1;
    }

    ns->getProperties()->push_back(p);
    pthread_mutex_unlock(&mLock);
    return 0;
}

int PropertyManager::detachProperty(const char *ns_name, Property *p) {
    PropertyNamespace *ns;

    ALOGD("Detaching property %s from namespace %s", p->getName(), ns_name);
    pthread_mutex_lock(&mLock);
    if (!(ns = lookupNamespace_UNLOCKED(ns_name))) {
        pthread_mutex_unlock(&mLock);
        ALOGE("Namespace '%s' not found", ns_name);
        return -1;
    }

    PropertyCollection::iterator it;

    for (it = ns->getProperties()->begin();
         it != ns->getProperties()->end(); ++it) {
        if (!strcasecmp(p->getName(), (*it)->getName())) {
            delete ((*it));
            ns->getProperties()->erase(it);
            pthread_mutex_unlock(&mLock);
            return 0;
        }
    }

    ALOGE("Property %s.%s not found", ns_name, p->getName());
    pthread_mutex_unlock(&mLock);
    errno = ENOENT;
    return -1;
}

int PropertyManager::doSet(Property *p, int idx, const char *value) {

    if (p->getReadOnly()) {
        errno = EROFS;
        return -1;
    }

    if (p->getType() == Property::Type_STRING) {
        return p->set(idx, value);
    } else if (p->getType() == Property::Type_INTEGER) {
        int tmp;
        errno = 0;
        tmp = strtol(value, (char **) NULL, 10);
        if (errno) {
            ALOGE("Failed to convert '%s' to int", value);
            errno = EINVAL;
            return -1;
        }
        return p->set(idx, tmp);
    } else if (p->getType() == Property::Type_IPV4) {
        struct in_addr tmp;
        if (!inet_aton(value, &tmp)) {
            ALOGE("Failed to convert '%s' to ipv4", value);
            errno = EINVAL;
            return -1;
        }
        return p->set(idx, &tmp);
    } else {
        ALOGE("Property '%s' has an unknown type (%d)", p->getName(),
             p->getType());
        errno = EINVAL;
        return -1;
    }
    errno = ENOENT;
    return -1;
}

int PropertyManager::doGet(Property *p, int idx, char *buffer, size_t max) {

    if (p->getType() == Property::Type_STRING) {
        if (p->get(idx, buffer, max)) {
            ALOGW("String property %s get failed (%s)", p->getName(),
                 strerror(errno));
            return -1;
        }
    }
    else if (p->getType() == Property::Type_INTEGER) {
        int tmp;
        if (p->get(idx, &tmp)) {
            ALOGW("Integer property %s get failed (%s)", p->getName(),
                 strerror(errno));
            return -1;
        }
        snprintf(buffer, max, "%d", tmp);
    } else if (p->getType() == Property::Type_IPV4) {
        struct in_addr tmp;
        if (p->get(idx, &tmp)) {
            ALOGW("IPV4 property %s get failed (%s)", p->getName(),
                 strerror(errno));
            return -1;
        }
        strncpy(buffer, inet_ntoa(tmp), max);
    } else {
        ALOGE("Property '%s' has an unknown type (%d)", p->getName(),
             p->getType());
        errno = EINVAL;
        return -1;
    }
    return 0;
}

/*
 * IPropertyManager methods
 */

int PropertyManager::set(const char *name, const char *value) {

    ALOGD("set %s = '%s'", name, value);
    pthread_mutex_lock(&mLock);
    PropertyNamespaceCollection::iterator ns_it;
    for (ns_it = mNamespaces->begin(); ns_it != mNamespaces->end(); ++ns_it) {
        PropertyCollection::iterator p_it;
        for (p_it = (*ns_it)->getProperties()->begin();
             p_it != (*ns_it)->getProperties()->end(); ++p_it) {
            for (int i = 0; i < (*p_it)->getNumElements(); i++) {
                char fqn[255];
                char tmp[8];
                sprintf(tmp, "_%d", i);
                snprintf(fqn, sizeof(fqn), "%s.%s%s",
                         (*ns_it)->getName(), (*p_it)->getName(),
                         ((*p_it)->getNumElements() > 1 ? tmp : ""));
                if (!strcasecmp(name, fqn)) {
                    pthread_mutex_unlock(&mLock);
                    return doSet((*p_it), i, value);
                }
            }
        }
    }

    ALOGE("Property %s not found", name);
    pthread_mutex_unlock(&mLock);
    errno = ENOENT;
    return -1;
}

const char *PropertyManager::get(const char *name, char *buffer, size_t max) {
    pthread_mutex_lock(&mLock);
    PropertyNamespaceCollection::iterator ns_it;
    for (ns_it = mNamespaces->begin(); ns_it != mNamespaces->end(); ++ns_it) {
        PropertyCollection::iterator p_it;
        for (p_it = (*ns_it)->getProperties()->begin();
             p_it != (*ns_it)->getProperties()->end(); ++p_it) {

            for (int i = 0; i < (*p_it)->getNumElements(); i++) {
                char fqn[255];
                char tmp[8];
                sprintf(tmp, "_%d", i);
                snprintf(fqn, sizeof(fqn), "%s.%s%s",
                         (*ns_it)->getName(), (*p_it)->getName(),
                         ((*p_it)->getNumElements() > 1 ? tmp : ""));
                if (!strcasecmp(name, fqn)) {
                    pthread_mutex_unlock(&mLock);
                    if (doGet((*p_it), i, buffer, max))
                        return NULL;
                    return buffer;
                }
            }
        }
    }

    ALOGE("Property %s not found", name);
    pthread_mutex_unlock(&mLock);
    errno = ENOENT;
    return NULL;
}

android::List<char *> *PropertyManager::createPropertyList(const char *prefix) {
    android::List<char *> *c = new android::List<char *>();

    pthread_mutex_lock(&mLock);
    PropertyNamespaceCollection::iterator ns_it;
    for (ns_it = mNamespaces->begin(); ns_it != mNamespaces->end(); ++ns_it) {
        PropertyCollection::iterator p_it;
        for (p_it = (*ns_it)->getProperties()->begin();
             p_it != (*ns_it)->getProperties()->end(); ++p_it) {
            for (int i = 0; i < (*p_it)->getNumElements(); i++) {
                char fqn[255];
                char tmp[8];
                sprintf(tmp, "_%d", i);
                snprintf(fqn, sizeof(fqn), "%s.%s%s",
                         (*ns_it)->getName(), (*p_it)->getName(),
                         ((*p_it)->getNumElements() > 1 ? tmp : ""));
                if (!prefix ||
                    (prefix && !strncasecmp(fqn, prefix, strlen(prefix)))) {
                    c->push_back(strdup(fqn));
                }
            }
        }
    }
    pthread_mutex_unlock(&mLock);
    return c;
}
