/*
 * 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.
 */

#include <string.h>
#include "os/mynewt.h"

static STAILQ_HEAD(, os_dev) g_os_dev_list;

static int
os_dev_init(struct os_dev *dev, char *name, uint8_t stage,
        uint8_t priority, os_dev_init_func_t od_init, void *arg)
{
    dev->od_name = name;
    dev->od_stage = stage;
    dev->od_priority = priority;
    /* assume these are set after the fact. */
    dev->od_flags = 0;
    dev->od_open_ref = 0;
    dev->od_init = od_init;
    dev->od_init_arg = arg;
    memset(&dev->od_handlers, 0, sizeof(dev->od_handlers));

    return (0);
}

/**
 * Add the device to the device tree.  This is a private function.
 *
 * @param dev The device to add to the device tree.
 *
 * @return 0 on success, non-zero on failure.
 */
static int
os_dev_add(struct os_dev *dev)
{
    struct os_dev *cur_dev;

    /* If no devices present, insert into head */
    if (STAILQ_FIRST(&g_os_dev_list) == NULL) {
        STAILQ_INSERT_HEAD(&g_os_dev_list, dev, od_next);
        return (0);
    }

    /* Add devices to the list, sorted first by stage, then by
     * priority.  Keep sorted in this order for initialization
     * stage.
     */
    cur_dev = NULL;
    STAILQ_FOREACH(cur_dev, &g_os_dev_list, od_next) {
        if (cur_dev->od_stage > dev->od_stage) {
            continue;
        }

        if (dev->od_priority >= cur_dev->od_priority) {
            break;
        }
    }

    if (cur_dev) {
        STAILQ_INSERT_AFTER(&g_os_dev_list, cur_dev, dev, od_next);
    } else {
        STAILQ_INSERT_TAIL(&g_os_dev_list, dev, od_next);
    }

    return (0);
}

/**
 * Call device initialize routine, and mark it ready. This is a private
 * function.
 *
 * @param dev The device to initialize.
 *
 * @return 0 on success, non-zero on failure.
 */
static int
os_dev_initialize(struct os_dev *dev)
{
    int rc;

    rc = dev->od_init(dev, dev->od_init_arg);
    if (rc != 0) {
        if (dev->od_flags & OS_DEV_F_INIT_CRITICAL) {
            goto err;
        }
    } else {
        dev->od_flags |= OS_DEV_F_STATUS_READY;
    }
    return 0;
err:
    return rc;
}

int
os_dev_create(struct os_dev *dev, char *name, uint8_t stage,
        uint8_t priority, os_dev_init_func_t od_init, void *arg)
{
    int rc;

    rc = os_dev_init(dev, name, stage, priority, od_init, arg);
    if (rc != 0) {
        goto err;
    }

    rc = os_dev_add(dev);
    if (rc != 0) {
        goto err;
    }

    if (g_os_started) {
        rc = os_dev_initialize(dev);
    }
err:
    return (rc);
}

int
os_dev_initialize_all(uint8_t stage)
{
    struct os_dev *dev;
    int rc = 0;

    STAILQ_FOREACH(dev, &g_os_dev_list, od_next) {
        if (dev->od_stage == stage) {
            rc = os_dev_initialize(dev);
            if (rc) {
                break;
            }
        }
    }

    return (rc);
}

int
os_dev_suspend_all(os_time_t suspend_t, uint8_t force)
{
    struct os_dev *dev;
    int suspend_failure;
    int rc;

    suspend_failure = 0;
    STAILQ_FOREACH(dev, &g_os_dev_list, od_next) {
        rc = os_dev_suspend(dev, suspend_t, force);
        if (rc != 0) {
            suspend_failure = OS_ERROR;
        }
    }

    return (suspend_failure);
}

int
os_dev_resume_all(void)
{
    struct os_dev *dev;
    int rc;

    STAILQ_FOREACH(dev, &g_os_dev_list, od_next) {
        rc = os_dev_resume(dev);
        if (rc != 0) {
            goto err;
        }
    }

    return (0);
err:
    return (rc);
}

struct os_dev *
os_dev_lookup(char *name)
{
    struct os_dev *dev;

    dev = NULL;
    STAILQ_FOREACH(dev, &g_os_dev_list, od_next) {
        if (!strcmp(dev->od_name, name)) {
            break;
        }
    }
    return (dev);
}

struct os_dev *
os_dev_open(char *devname, uint32_t timo, void *arg)
{
    struct os_dev *dev;
    os_sr_t sr;
    int rc;

    dev = os_dev_lookup(devname);
    if (dev == NULL) {
        return (NULL);
    }

    /* Device is not ready to be opened. */
    if ((dev->od_flags & OS_DEV_F_STATUS_READY) == 0) {
        return (NULL);
    }

    if (dev->od_handlers.od_open) {
        rc = dev->od_handlers.od_open(dev, timo, arg);
        if (rc != 0) {
            goto err;
        }
    }

    OS_ENTER_CRITICAL(sr);
    ++dev->od_open_ref;
    dev->od_flags |= OS_DEV_F_STATUS_OPEN;
    OS_EXIT_CRITICAL(sr);

    return (dev);
err:
    return (NULL);
}

int
os_dev_close(struct os_dev *dev)
{
    int rc;
    os_sr_t sr;

    if (dev->od_handlers.od_close) {
        rc = dev->od_handlers.od_close(dev);
        if (rc != 0) {
            goto err;
        }
    }

    OS_ENTER_CRITICAL(sr);
    if (--dev->od_open_ref == 0) {
        dev->od_flags &= ~(OS_DEV_F_STATUS_OPEN | OS_DEV_F_STATUS_SUSPENDED);
    }
    OS_EXIT_CRITICAL(sr);

    return (0);
err:
    return (rc);
}

int
os_dev_suspend(struct os_dev *dev, os_time_t suspend_t, uint8_t force)
{
    os_sr_t sr;
    int rc;

    OS_ENTER_CRITICAL(sr);
    if (!(dev->od_flags & OS_DEV_F_STATUS_OPEN)) {
        OS_EXIT_CRITICAL(sr);
        return OS_EINVAL;
    }
    if (dev->od_flags & OS_DEV_F_STATUS_SUSPENDED) {
        OS_EXIT_CRITICAL(sr);
        return OS_OK;
    }
    OS_EXIT_CRITICAL(sr);

    if (dev->od_handlers.od_suspend) {
        rc = dev->od_handlers.od_suspend(dev, suspend_t, force);
        if (rc) {
            return rc;
        }
    }

    OS_ENTER_CRITICAL(sr);
    dev->od_flags |= OS_DEV_F_STATUS_SUSPENDED;
    OS_EXIT_CRITICAL(sr);

    return OS_OK;
}

int
os_dev_resume(struct os_dev *dev)
{
    os_sr_t sr;
    int rc;

    OS_ENTER_CRITICAL(sr);
    if (!(dev->od_flags & OS_DEV_F_STATUS_SUSPENDED)) {
        OS_EXIT_CRITICAL(sr);
        return OS_EINVAL;
    }
    OS_EXIT_CRITICAL(sr);

    if (dev->od_handlers.od_resume) {
        rc = dev->od_handlers.od_resume(dev);
        if (rc) {
            return rc;
        }
    }

    OS_ENTER_CRITICAL(sr);
    dev->od_flags &= ~OS_DEV_F_STATUS_SUSPENDED;
    OS_EXIT_CRITICAL(sr);

    return OS_OK;
}

void
os_dev_reset(void)
{
    STAILQ_INIT(&g_os_dev_list);
}

