/*
 * 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 <assert.h>
#include <string.h>
#include "defs/error.h"
#include "bus/bus.h"
#include "bus/bus_debug.h"
#include "bus/bus_driver.h"
#if MYNEWT_VAL(BUS_STATS)
#include "stats/stats.h"
#endif

static os_time_t g_bus_node_lock_timeout;

#if MYNEWT_VAL(BUS_STATS)
STATS_NAME_START(bus_stats_section)
    STATS_NAME(bus_stats_section, lock_timeouts)
    STATS_NAME(bus_stats_section, read_ops)
    STATS_NAME(bus_stats_section, read_errors)
    STATS_NAME(bus_stats_section, write_ops)
    STATS_NAME(bus_stats_section, write_errors)
STATS_NAME_END(bus_stats_section)

#if MYNEWT_VAL(BUS_STATS_PER_NODE)
#define BUS_STATS_INC(_bdev, _bnode, _var)  \
    do {                                    \
        STATS_INC((_bdev)->stats, _var);    \
        STATS_INC((_bnode)->stats, _var);   \
    } while (0)
#else
#define BUS_STATS_INC(_bdev, _bnode, _var)  \
    do {                                    \
        STATS_INC((_bdev)->stats, _var);    \
    } while (0)
#endif
#else
#define BUS_STATS_INC(_bdev, _bnode, _var)  \
    do {                                    \
    } while (0)
#endif

static inline void
bus_dev_enable(struct bus_dev *bdev)
{
    if (bdev->enabled) {
        return;
    }

    if (bdev->dops->enable) {
        bdev->dops->enable(bdev);
    }

    bdev->enabled = true;
}

static inline void
bus_dev_disable(struct bus_dev *bdev)
{
    if (!bdev->enabled) {
        return;
    }

    if (bdev->dops->disable) {
        bdev->dops->disable(bdev);
    }

    bdev->enabled = false;
}

static int
bus_dev_suspend_func(struct os_dev *odev, os_time_t suspend_at, int force)
{
    struct bus_dev *bdev = (struct bus_dev *)odev;
    int rc;

#if MYNEWT_VAL(BUS_PM)
    if (bdev->pm_mode != BUS_PM_MODE_MANUAL) {
        return OS_EINVAL;
    }
#endif

    /* To make things simple we just allow to suspend "now" */
    if (OS_TIME_TICK_GT(suspend_at, os_time_get())) {
        return OS_EINVAL;
    }

    rc = os_mutex_pend(&bdev->lock, OS_TIMEOUT_NEVER);
    if (rc) {
        return rc;
    }

    bus_dev_disable(bdev);

    os_mutex_release(&bdev->lock);

    return OS_OK;
}

static int
bus_dev_resume_func(struct os_dev *odev)
{
    struct bus_dev *bdev = (struct bus_dev *)odev;
    int rc;

#if MYNEWT_VAL(BUS_PM)
    if (bdev->pm_mode != BUS_PM_MODE_MANUAL) {
        return OS_EINVAL;
    }
#endif

    rc = os_mutex_pend(&bdev->lock, OS_TIMEOUT_NEVER);
    if (rc) {
        return rc;
    }

    bus_dev_enable(bdev);

    os_mutex_release(&bdev->lock);

    return OS_OK;
}

#if MYNEWT_VAL(BUS_PM)
static void
bus_dev_inactivity_tmo_func(struct os_event *ev)
{
    struct bus_dev *bdev = (struct bus_dev *)ev->ev_arg;
    int rc;

    rc = os_mutex_pend(&bdev->lock, OS_TIMEOUT_NEVER);
    if (rc) {
        return;
    }

    /* Just in case PM was changed while timer was running */
    if (bdev->pm_mode == BUS_PM_MODE_AUTO) {
        bus_dev_disable(bdev);
    }

    os_mutex_release(&bdev->lock);
}
#endif

static int
bus_node_open_func(struct os_dev *odev, uint32_t wait, void *arg)
{
    struct bus_node *bnode = (struct bus_node *)odev;

    BUS_DEBUG_VERIFY_NODE(bnode);

    if (!bnode->callbacks.open) {
        return 0;
    }

    /*
     * XXX current os_dev implementation is prone to races since reference
     * counting is done without any locking, we'll need to fix it there
     */

    /* Call open callback if opening first ref */
    if (odev->od_open_ref == 0) {
        bnode->callbacks.open(bnode);
    }

    return 0;
}

static int
bus_node_close_func(struct os_dev *odev)
{
    struct bus_node *bnode = (struct bus_node *)odev;

    BUS_DEBUG_VERIFY_NODE(bnode);

    if (!bnode->callbacks.close) {
        return 0;
    }

    /*
     * XXX current os_dev implementation is prone to races since reference
     * counting is done without any locking, we'll need to fix it there
     */

    /* Call close callback if closing last ref */
    if (odev->od_open_ref == 1) {
        bnode->callbacks.close(bnode);
    }

    return 0;
}

void
bus_node_set_callbacks(struct os_dev *node, struct bus_node_callbacks *cbs)
{
    struct bus_node *bnode = (struct bus_node *)node;

    /* This should be done only once so all callbacks should be NULL here */
    assert(bnode->callbacks.init == NULL);
    assert(bnode->callbacks.open == NULL);
    assert(bnode->callbacks.close == NULL);

    bnode->callbacks = *cbs;
}

int
bus_dev_init_func(struct os_dev *odev, void *arg)
{
    struct bus_dev *bdev = (struct bus_dev *)odev;
    struct bus_dev_ops *ops = arg;
#if MYNEWT_VAL(BUS_STATS)
    char *stats_name;
    int rc;
#endif

    BUS_DEBUG_POISON_DEV(bdev);

    bdev->dops = ops;
    bdev->configured_for = NULL;

    os_mutex_init(&bdev->lock);
#if MYNEWT_VAL(BUS_PM)
    /* XXX allow custom eventq */
    os_callout_init(&bdev->inactivity_tmo, os_eventq_dflt_get(),
                    bus_dev_inactivity_tmo_func, odev);
    bdev->pm_mode = MYNEWT_VAL_CHOICE(BUS_PM_MODE, AUTO) ? BUS_PM_MODE_AUTO : BUS_PM_MODE_MANUAL;
    if (MYNEWT_VAL_CHOICE(BUS_PM_MODE, AUTO)) {
        bdev->pm_opts.pm_mode_auto.disable_tmo = MYNEWT_VAL(BUS_PM_INACTIVITY_TMO);
    }
#endif

#if MYNEWT_VAL(BUS_STATS)
    asprintf(&stats_name, "bd_%s", odev->od_name);
    rc = stats_init_and_reg(STATS_HDR(bdev->stats),
                            STATS_SIZE_INIT_PARMS(bdev->stats, STATS_SIZE_32),
                            STATS_NAME_INIT_PARMS(bus_stats_section),
                            stats_name);
    assert(rc == 0);
#endif

    odev->od_handlers.od_suspend = bus_dev_suspend_func;
    odev->od_handlers.od_resume = bus_dev_resume_func;

    if (!MYNEWT_VAL(BUS_PM) || MYNEWT_VAL_CHOICE(BUS_PM_MODE, MANUAL)) {
        bus_dev_enable(bdev);
    }

    return 0;
}

int
bus_node_init_func(struct os_dev *odev, void *arg)
{
    struct bus_node *bnode = (struct bus_node *)odev;
    struct bus_node_cfg *node_cfg = arg;
    struct os_dev *parent_odev;
    struct bus_dev *bdev;
    void *init_arg;
#if MYNEWT_VAL(BUS_STATS_PER_NODE)
    char *stats_name;
#endif
    int rc;

    parent_odev = os_dev_lookup(node_cfg->bus_name);
    if (!parent_odev) {
        return OS_EINVAL;
    }

    BUS_DEBUG_POISON_NODE(bnode);

    /* We need to save init_arg here since it will be overwritten by parent_bus */
    init_arg = bnode->init_arg;
    bnode->parent_bus = (struct bus_dev *)parent_odev;

    bdev = (struct bus_dev *)parent_odev;
    rc = bdev->dops->init_node(bdev, bnode, arg);
    if (rc) {
        return rc;
    }

    if (node_cfg->lock_timeout_ms) {
        bnode->lock_timeout = os_time_ms_to_ticks32(node_cfg->lock_timeout_ms);
    } else {
        /* Use default */
        bnode->lock_timeout = 0;
    }

    odev->od_handlers.od_open = bus_node_open_func;
    odev->od_handlers.od_close = bus_node_close_func;

#if MYNEWT_VAL(BUS_STATS_PER_NODE)
    asprintf(&stats_name, "bn_%s", odev->od_name);
    rc = stats_init_and_reg(STATS_HDR(bnode->stats),
                            STATS_SIZE_INIT_PARMS(bnode->stats, STATS_SIZE_32),
                            STATS_NAME_INIT_PARMS(bus_stats_section),
                            stats_name);
    assert(rc == 0);
#endif

    if (bnode->callbacks.init) {
        bnode->callbacks.init(bnode, init_arg);
    }

    return 0;
}

int
bus_node_read(struct os_dev *node, void *buf, uint16_t length,
              os_time_t timeout, uint16_t flags)
{
    struct bus_node *bnode = (struct bus_node *)node;
    struct bus_dev *bdev = bnode->parent_bus;
    int rc;

    BUS_DEBUG_VERIFY_DEV(bdev);
    BUS_DEBUG_VERIFY_NODE(bnode);

    if (!bdev->dops->read) {
        return SYS_ENOTSUP;
    }

    rc = bus_node_lock(node, bus_node_get_lock_timeout(node));
    if (rc) {
        return rc;
    }

    if (!bdev->enabled) {
        rc = SYS_EIO;
        goto done;
    }

    BUS_STATS_INC(bdev, bnode, read_ops);
    rc = bdev->dops->read(bdev, bnode, buf, length, timeout, flags);
    if (rc) {
        BUS_STATS_INC(bdev, bnode, read_errors);
    }

done:
    (void)bus_node_unlock(node);

    return rc;
}

int
bus_node_write(struct os_dev *node, const void *buf, uint16_t length,
               os_time_t timeout, uint16_t flags)
{
    struct bus_node *bnode = (struct bus_node *)node;
    struct bus_dev *bdev = bnode->parent_bus;
    int rc;

    BUS_DEBUG_VERIFY_DEV(bdev);
    BUS_DEBUG_VERIFY_NODE(bnode);

    if (!bdev->dops->write) {
        return SYS_ENOTSUP;
    }

    rc = bus_node_lock(node, bus_node_get_lock_timeout(node));
    if (rc) {
        return rc;
    }

    if (!bdev->enabled) {
        rc = SYS_EIO;
        goto done;
    }

    BUS_STATS_INC(bdev, bnode, write_ops);
    rc = bdev->dops->write(bdev, bnode, buf, length, timeout, flags);
    if (rc) {
        BUS_STATS_INC(bdev, bnode, write_errors);
    }

done:
    (void)bus_node_unlock(node);

    return rc;
}

int
bus_node_write_read_transact(struct os_dev *node, const void *wbuf,
                             uint16_t wlength, void *rbuf, uint16_t rlength,
                             os_time_t timeout, uint16_t flags)
{
    struct bus_node *bnode = (struct bus_node *)node;
    struct bus_dev *bdev = bnode->parent_bus;
    int rc;

    BUS_DEBUG_VERIFY_DEV(bdev);
    BUS_DEBUG_VERIFY_NODE(bnode);

    if (!bdev->dops->write || !bdev->dops->read) {
        return SYS_ENOTSUP;
    }

    rc = bus_node_lock(node, bus_node_get_lock_timeout(node));
    if (rc) {
        return rc;
    }

    if (!bdev->enabled) {
        rc = SYS_EIO;
        goto done;
    }

    if (bdev->dops->write_read) {
        BUS_STATS_INC(bdev, bnode, write_ops);
        BUS_STATS_INC(bdev, bnode, read_ops);
        rc = bdev->dops->write_read(bdev, bnode, wbuf, wlength, rbuf, rlength, timeout, flags);
        if (rc) {
            BUS_STATS_INC(bdev, bnode, write_errors);
            BUS_STATS_INC(bdev, bnode, read_errors);
        }
    } else {
        /*
         * XXX we probably should pass flags here but with some of them stripped,
         * e.g. BUS_F_NOSTOP should not be present here, but since we do not have
         * too many flags now (like we literally have only one flag) let's just pass
         * no flags for now
         */
        BUS_STATS_INC(bdev, bnode, write_ops);
        rc = bdev->dops->write(bdev, bnode, wbuf, wlength, timeout, BUS_F_NOSTOP);
        if (rc) {
            BUS_STATS_INC(bdev, bnode, write_errors);
            goto done;
        }

        BUS_STATS_INC(bdev, bnode, read_ops);
        rc = bdev->dops->read(bdev, bnode, rbuf, rlength, timeout, flags);
        if (rc) {
            BUS_STATS_INC(bdev, bnode, read_errors);
            goto done;
        }
    }

done:
    (void)bus_node_unlock(node);

    return rc;
}


int
bus_node_lock(struct os_dev *node, os_time_t timeout)
{
    struct bus_node *bnode = (struct bus_node *)node;
    struct bus_dev *bdev = bnode->parent_bus;
    os_error_t err;
    int rc;

    BUS_DEBUG_VERIFY_DEV(bdev);
    BUS_DEBUG_VERIFY_NODE(bnode);

    if (timeout == BUS_NODE_LOCK_DEFAULT_TIMEOUT) {
        timeout = g_bus_node_lock_timeout;
    }

    err = os_mutex_pend(&bdev->lock, timeout);
    if (err == OS_TIMEOUT) {
        BUS_STATS_INC(bdev, bnode, lock_timeouts);
        return SYS_ETIMEOUT;
    }

    assert(err == OS_OK || err == OS_NOT_STARTED);

#if MYNEWT_VAL(BUS_PM)
    /* In auto PM we need to enable bus device on first lock */
    if ((bdev->pm_mode == BUS_PM_MODE_AUTO) &&
        (os_mutex_get_level(&bdev->lock) == 1)) {
        os_callout_stop(&bdev->inactivity_tmo);
        bus_dev_enable(bdev);
    }
#endif

    /* No need to configure if already configured for the same node */
    if (bdev->configured_for == bnode) {
        return 0;
    }

    /*
     * Configuration is done on 1st lock so in case we need to configure device
     * on nested lock it means that most likely bus device was locked for one
     * node and then access is done on another node which is not correct.
     */
    if (os_mutex_get_level(&bdev->lock) != 1) {
        (void)bus_node_unlock(node);
        return SYS_EACCES;
    }

    rc = bdev->dops->configure(bdev, bnode);
    if (rc) {
        bdev->configured_for = NULL;
        (void)bus_node_unlock(node);
    } else {
        bdev->configured_for = bnode;
    }

    return rc;
}

int
bus_node_unlock(struct os_dev *node)
{
    struct bus_node *bnode = (struct bus_node *)node;
    struct bus_dev *bdev = bnode->parent_bus;
    os_error_t err;

    BUS_DEBUG_VERIFY_DEV(bdev);
    BUS_DEBUG_VERIFY_NODE(bnode);

#if MYNEWT_VAL(BUS_PM)
    /* In auto PM we should disable bus device on last unlock */
    if ((bdev->pm_mode == BUS_PM_MODE_AUTO) &&
        (os_mutex_get_level(&bdev->lock) == 1)) {
        if (bdev->pm_opts.pm_mode_auto.disable_tmo == 0) {
            bus_dev_disable(bdev);
        } else {
            os_callout_reset(&bdev->inactivity_tmo,
                             bdev->pm_opts.pm_mode_auto.disable_tmo);
        }
    }
#endif

    err = os_mutex_release(&bdev->lock);

    /*
     * Probably no one cares about return value from unlock, so for debugging
     * purposes let's assert on anything that is not a success. This includes
     * OS_INVALID_PARM (we basically can't pass invalid mutex here unless our
     * structs are broken) and OS_BAD_MUTEX (unlock shall be only done by the
     * same task which locked it).
     */
    assert(err == OS_OK || err == OS_NOT_STARTED);

    return 0;
}

os_time_t
bus_node_get_lock_timeout(struct os_dev *node)
{
    struct bus_node *bnode = (struct bus_node *)node;

    BUS_DEBUG_VERIFY_NODE(bnode);

    return bnode->lock_timeout ? bnode->lock_timeout : g_bus_node_lock_timeout;
}

int
bus_dev_set_pm(struct os_dev *bus, bus_pm_mode_t pm_mode,
               union bus_pm_options *pm_opts)
{
#if MYNEWT_VAL(BUS_PM)
    struct bus_dev *bdev = (struct bus_dev *)bus;
    int rc;

    BUS_DEBUG_VERIFY_DEV(bdev);

    rc = os_mutex_pend(&bdev->lock, OS_TIMEOUT_NEVER);
    if (rc) {
        return SYS_EACCES;
    }

    bdev->pm_mode = pm_mode;

    if (pm_opts) {
        memcpy(&bdev->pm_opts, pm_opts, sizeof(*pm_opts));
    } else {
        memset(&bdev->pm_opts, 0, sizeof(*pm_opts));
    }

    os_mutex_release(&bdev->lock);

    return 0;
#else
    return SYS_ENOTSUP;
#endif
}

void
bus_pkg_init(void)
{
    uint32_t lock_timeout_ms;

    lock_timeout_ms = MYNEWT_VAL(BUS_DEFAULT_LOCK_TIMEOUT_MS);

    g_bus_node_lock_timeout = os_time_ms_to_ticks32(lock_timeout_ms);
}
