/*
 * Copyright (C) 2015 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.
 */

#define LOG_TAG "radio_hw_stub"
#define LOG_NDEBUG 0

#include <string.h>
#include <stdlib.h>
#include <errno.h>
#include <pthread.h>
#include <sys/prctl.h>
#include <sys/time.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <cutils/log.h>
#include <cutils/list.h>
#include <system/radio.h>
#include <system/radio_metadata.h>
#include <hardware/hardware.h>
#include <hardware/radio.h>

static const radio_hal_properties_t hw_properties = {
    .class_id = RADIO_CLASS_AM_FM,
    .implementor = "The Android Open Source Project",
    .product = "Radio stub HAL",
    .version = "0.1",
    .serial = "0123456789",
    .num_tuners = 1,
    .num_audio_sources = 1,
    .supports_capture = false,
    .num_bands = 2,
    .bands = {
        {
            .type = RADIO_BAND_FM,
            .antenna_connected = false,
            .lower_limit = 87900,
            .upper_limit = 107900,
            .num_spacings = 1,
            .spacings = { 200 },
            .fm = {
                .deemphasis = RADIO_DEEMPHASIS_75,
                .stereo = true,
                .rds = RADIO_RDS_US,
                .ta = false,
                .af = false,
            }
        },
        {
            .type = RADIO_BAND_AM,
            .antenna_connected = true,
            .lower_limit = 540,
            .upper_limit = 1610,
            .num_spacings = 1,
            .spacings = { 10 },
            .am = {
                .stereo = true,
            }
        }
    }
};

struct stub_radio_tuner {
    struct radio_tuner interface;
    struct stub_radio_device *dev;
    radio_callback_t callback;
    void *cookie;
    radio_hal_band_config_t config;
    radio_program_info_t program;
    bool audio;
    pthread_t callback_thread;
    pthread_mutex_t lock;
    pthread_cond_t  cond;
    struct listnode command_list;
};

struct stub_radio_device {
    struct radio_hw_device device;
    struct stub_radio_tuner *tuner;
    pthread_mutex_t lock;
};


typedef enum {
    CMD_EXIT,
    CMD_CONFIG,
    CMD_STEP,
    CMD_SCAN,
    CMD_TUNE,
    CMD_CANCEL,
    CMD_METADATA,
} thread_cmd_type_t;

struct thread_command {
    struct listnode node;
    thread_cmd_type_t type;
    struct timespec ts;
    union {
        unsigned int param;
        radio_hal_band_config_t config;
    };
};

/* must be called with out->lock locked */
static int send_command_l(struct stub_radio_tuner *tuner,
                          thread_cmd_type_t type,
                          unsigned int delay_ms,
                          void *param)
{
    struct thread_command *cmd = (struct thread_command *)calloc(1, sizeof(struct thread_command));
    struct timespec ts;

    if (cmd == NULL)
        return -ENOMEM;

    ALOGV("%s %d delay_ms %d", __func__, type, delay_ms);

    cmd->type = type;
    if (param != NULL) {
        if (cmd->type == CMD_CONFIG) {
            cmd->config = *(radio_hal_band_config_t *)param;
            ALOGV("%s CMD_CONFIG type %d", __func__, cmd->config.type);
        } else
            cmd->param = *(unsigned int *)param;
    }

    clock_gettime(CLOCK_REALTIME, &ts);

    ts.tv_sec  += delay_ms/1000;
    ts.tv_nsec += (delay_ms%1000) * 1000000;
    if (ts.tv_nsec >= 1000000000) {
        ts.tv_nsec -= 1000000000;
        ts.tv_sec  += 1;
    }
    cmd->ts = ts;
    list_add_tail(&tuner->command_list, &cmd->node);
    pthread_cond_signal(&tuner->cond);
    return 0;
}

#define BITMAP_FILE_PATH "/data/misc/media/android.png"

static int add_bitmap_metadata(radio_metadata_t **metadata, radio_metadata_key_t key,
                               const char *source)
{
    int fd;
    ssize_t ret = 0;
    struct stat info;
    void *data = NULL;
    size_t size;

    fd = open(source, O_RDONLY);
    if (fd < 0)
        return -EPIPE;

    fstat(fd, &info);
    size = info.st_size;
    data = malloc(size);
    if (data == NULL) {
        ret = -ENOMEM;
        goto exit;
    }
    ret = read(fd, data, size);
    if (ret < 0)
        goto exit;
    ret = radio_metadata_add_raw(metadata, key, (const unsigned char *)data, size);

exit:
    close(fd);
    free(data);
    ALOGE_IF(ret != 0, "%s error %d", __func__, ret);
    return (int)ret;
}

static int prepare_metadata(struct stub_radio_tuner *tuner,
                            radio_metadata_t **metadata, bool program)
{
    int ret = 0;
    char text[RADIO_STRING_LEN_MAX];
    struct timespec ts;

    if (metadata == NULL)
        return -EINVAL;

    if (*metadata != NULL)
        radio_metadata_deallocate(*metadata);

    *metadata = NULL;

    ret = radio_metadata_allocate(metadata, tuner->program.channel, 0);
    if (ret != 0)
        return ret;

    if (program) {
        ret = radio_metadata_add_int(metadata, RADIO_METADATA_KEY_RBDS_PTY, 5);
        if (ret != 0)
            goto exit;
        ret = radio_metadata_add_text(metadata, RADIO_METADATA_KEY_RDS_PS, "RockBand");
        if (ret != 0)
            goto exit;
        ret = add_bitmap_metadata(metadata, RADIO_METADATA_KEY_ICON, BITMAP_FILE_PATH);
        if (ret != 0)
            goto exit;
    } else {
        ret = add_bitmap_metadata(metadata, RADIO_METADATA_KEY_ART, BITMAP_FILE_PATH);
        if (ret != 0)
            goto exit;
    }

    clock_gettime(CLOCK_REALTIME, &ts);
    snprintf(text, RADIO_STRING_LEN_MAX, "Artist %ld", ts.tv_sec % 10);
    ret = radio_metadata_add_text(metadata, RADIO_METADATA_KEY_ARTIST, text);
    if (ret != 0)
        goto exit;

    snprintf(text, RADIO_STRING_LEN_MAX, "Song %ld", ts.tv_nsec % 10);
    ret = radio_metadata_add_text(metadata, RADIO_METADATA_KEY_TITLE, text);
    if (ret != 0)
        goto exit;

    return 0;

exit:
    radio_metadata_deallocate(*metadata);
    *metadata = NULL;
    return ret;
}

static void *callback_thread_loop(void *context)
{
    struct stub_radio_tuner *tuner = (struct stub_radio_tuner *)context;
    struct timespec ts = {0, 0};

    ALOGI("%s", __func__);

    prctl(PR_SET_NAME, (unsigned long)"sound trigger callback", 0, 0, 0);

    pthread_mutex_lock(&tuner->lock);

    while (true) {
        struct thread_command *cmd = NULL;
        struct listnode *item;
        struct listnode *tmp;
        struct timespec cur_ts;
        bool got_cancel = false;
        bool send_meta_data = false;

        if (list_empty(&tuner->command_list) || ts.tv_sec != 0) {
            ALOGV("%s SLEEPING", __func__);
            if (ts.tv_sec != 0) {
                ALOGV("%s SLEEPING with timeout", __func__);
                pthread_cond_timedwait(&tuner->cond, &tuner->lock, &ts);
            } else {
                ALOGV("%s SLEEPING forever", __func__);
                pthread_cond_wait(&tuner->cond, &tuner->lock);
            }
            ts.tv_sec = 0;
            ALOGV("%s RUNNING", __func__);
        }

        clock_gettime(CLOCK_REALTIME, &cur_ts);

        list_for_each_safe(item, tmp, &tuner->command_list) {
            cmd = node_to_item(item, struct thread_command, node);

            if (got_cancel && (cmd->type == CMD_STEP || cmd->type == CMD_SCAN ||
                    cmd->type == CMD_TUNE || cmd->type == CMD_METADATA)) {
                 list_remove(item);
                 free(cmd);
                 continue;
            }

            if ((cmd->ts.tv_sec < cur_ts.tv_sec) ||
                    ((cmd->ts.tv_sec == cur_ts.tv_sec) && (cmd->ts.tv_nsec < cur_ts.tv_nsec))) {
                radio_hal_event_t event;
                radio_metadata_t *metadata = NULL;

                event.type = RADIO_EVENT_HW_FAILURE;
                list_remove(item);

                ALOGV("%s processing command %d time %ld.%ld", __func__, cmd->type, cmd->ts.tv_sec,
                      cmd->ts.tv_nsec);

                switch (cmd->type) {
                default:
                case CMD_EXIT:
                    free(cmd);
                    goto exit;

                case CMD_CONFIG: {
                    tuner->config = cmd->config;
                    event.type = RADIO_EVENT_CONFIG;
                    event.config = tuner->config;
                    ALOGV("%s CMD_CONFIG type %d low %d up %d",
                          __func__, tuner->config.type,
                          tuner->config.lower_limit, tuner->config.upper_limit);
                    if (tuner->config.type == RADIO_BAND_FM) {
                        ALOGV("  - stereo %d\n  - rds %d\n  - ta %d\n  - af %d",
                              tuner->config.fm.stereo, tuner->config.fm.rds,
                              tuner->config.fm.ta, tuner->config.fm.af);
                    } else {
                        ALOGV("  - stereo %d", tuner->config.am.stereo);
                    }
                } break;

                case CMD_STEP: {
                    int frequency;
                    frequency = tuner->program.channel;
                    if (cmd->param == RADIO_DIRECTION_UP) {
                        frequency += tuner->config.spacings[0];
                    } else {
                        frequency -= tuner->config.spacings[0];
                    }
                    if (frequency > (int)tuner->config.upper_limit) {
                        frequency = tuner->config.lower_limit;
                    }
                    if (frequency < (int)tuner->config.lower_limit) {
                        frequency = tuner->config.upper_limit;
                    }
                    tuner->program.channel = frequency;
                    tuner->program.tuned  = (frequency / (tuner->config.spacings[0] * 5)) % 2;
                    tuner->program.signal_strength = 20;
                    if (tuner->config.type == RADIO_BAND_FM)
                        tuner->program.stereo = false;
                    else
                        tuner->program.stereo = false;

                    event.type = RADIO_EVENT_TUNED;
                    event.info = tuner->program;
                } break;

                case CMD_SCAN: {
                    int frequency;
                    frequency = tuner->program.channel;
                    if (cmd->param == RADIO_DIRECTION_UP) {
                        frequency += tuner->config.spacings[0] * 25;
                    } else {
                        frequency -= tuner->config.spacings[0] * 25;
                    }
                    if (frequency > (int)tuner->config.upper_limit) {
                        frequency = tuner->config.lower_limit;
                    }
                    if (frequency < (int)tuner->config.lower_limit) {
                        frequency = tuner->config.upper_limit;
                    }
                    tuner->program.channel = (unsigned int)frequency;
                    tuner->program.tuned  = true;
                    if (tuner->config.type == RADIO_BAND_FM)
                        tuner->program.stereo = tuner->config.fm.stereo;
                    else
                        tuner->program.stereo = tuner->config.am.stereo;
                    tuner->program.signal_strength = 50;

                    event.type = RADIO_EVENT_TUNED;
                    event.info = tuner->program;
                    send_meta_data = true;
                } break;

                case CMD_TUNE: {
                    tuner->program.channel = cmd->param;
                    tuner->program.tuned  = (tuner->program.channel /
                                                (tuner->config.spacings[0] * 5)) % 2;

                    if (tuner->program.tuned) {
                        prepare_metadata(tuner, &tuner->program.metadata, true);
                        send_command_l(tuner, CMD_METADATA, 5000, NULL);
                    } else {
                        if (tuner->program.metadata != NULL)
                            radio_metadata_deallocate(tuner->program.metadata);
                        tuner->program.metadata = NULL;
                    }
                    tuner->program.signal_strength = 100;
                    if (tuner->config.type == RADIO_BAND_FM)
                        tuner->program.stereo =
                                tuner->program.tuned ? tuner->config.fm.stereo : false;
                    else
                        tuner->program.stereo =
                            tuner->program.tuned ? tuner->config.am.stereo : false;
                    event.type = RADIO_EVENT_TUNED;
                    event.info = tuner->program;
                    send_meta_data = true;
                } break;

                case CMD_METADATA: {
                    int ret = prepare_metadata(tuner, &metadata, false);
                    if (ret == 0) {
                        event.type = RADIO_EVENT_METADATA;
                        event.metadata = metadata;
                    }
                    send_meta_data = true;
                } break;

                case CMD_CANCEL: {
                    got_cancel = true;
                } break;

                }
                if (event.type != RADIO_EVENT_HW_FAILURE && tuner->callback != NULL) {
                    pthread_mutex_unlock(&tuner->lock);
                    tuner->callback(&event, tuner->cookie);
                    pthread_mutex_lock(&tuner->lock);
                    if (event.type == RADIO_EVENT_METADATA && metadata != NULL) {
                        radio_metadata_deallocate(metadata);
                        metadata = NULL;
                    }
                }
                ALOGV("%s processed command %d", __func__, cmd->type);
                free(cmd);
            } else {
                if ((ts.tv_sec == 0) ||
                        (cmd->ts.tv_sec < ts.tv_sec) ||
                        ((cmd->ts.tv_sec == ts.tv_sec) && (cmd->ts.tv_nsec < ts.tv_nsec))) {
                    ts.tv_sec = cmd->ts.tv_sec;
                    ts.tv_nsec = cmd->ts.tv_nsec;
                }
            }
        }

        if (send_meta_data) {
            list_for_each_safe(item, tmp, &tuner->command_list) {
                cmd = node_to_item(item, struct thread_command, node);
                if (cmd->type == CMD_METADATA) {
                    list_remove(item);
                    free(cmd);
                }
            }
            send_command_l(tuner, CMD_METADATA, 100, NULL);
        }
    }

exit:
    pthread_mutex_unlock(&tuner->lock);

    ALOGV("%s Exiting", __func__);

    return NULL;
}


static int tuner_set_configuration(const struct radio_tuner *tuner,
                         const radio_hal_band_config_t *config)
{
    struct stub_radio_tuner *stub_tuner = (struct stub_radio_tuner *)tuner;
    int status = 0;

    ALOGI("%s stub_tuner %p", __func__, stub_tuner);
    pthread_mutex_lock(&stub_tuner->lock);
    if (config == NULL) {
        status = -EINVAL;
        goto exit;
    }
    send_command_l(stub_tuner, CMD_CANCEL, 0, NULL);
    send_command_l(stub_tuner, CMD_CONFIG, 500, (void *)config);

exit:
    pthread_mutex_unlock(&stub_tuner->lock);
    return status;
}

static int tuner_get_configuration(const struct radio_tuner *tuner,
                         radio_hal_band_config_t *config)
{
    struct stub_radio_tuner *stub_tuner = (struct stub_radio_tuner *)tuner;
    int status = 0;
    struct listnode *item;
    radio_hal_band_config_t *src_config;

    ALOGI("%s stub_tuner %p", __func__, stub_tuner);
    pthread_mutex_lock(&stub_tuner->lock);
    src_config = &stub_tuner->config;

    if (config == NULL) {
        status = -EINVAL;
        goto exit;
    }
    list_for_each(item, &stub_tuner->command_list) {
        struct thread_command *cmd = node_to_item(item, struct thread_command, node);
        if (cmd->type == CMD_CONFIG) {
            src_config = &cmd->config;
        }
    }
    *config = *src_config;

exit:
    pthread_mutex_unlock(&stub_tuner->lock);
    return status;
}

static int tuner_step(const struct radio_tuner *tuner,
                     radio_direction_t direction, bool skip_sub_channel)
{
    struct stub_radio_tuner *stub_tuner = (struct stub_radio_tuner *)tuner;

    ALOGI("%s stub_tuner %p direction %d, skip_sub_channel %d",
          __func__, stub_tuner, direction, skip_sub_channel);

    pthread_mutex_lock(&stub_tuner->lock);
    send_command_l(stub_tuner, CMD_STEP, 20, &direction);
    pthread_mutex_unlock(&stub_tuner->lock);
    return 0;
}

static int tuner_scan(const struct radio_tuner *tuner,
                     radio_direction_t direction, bool skip_sub_channel)
{
    struct stub_radio_tuner *stub_tuner = (struct stub_radio_tuner *)tuner;

    ALOGI("%s stub_tuner %p direction %d, skip_sub_channel %d",
          __func__, stub_tuner, direction, skip_sub_channel);

    pthread_mutex_lock(&stub_tuner->lock);
    send_command_l(stub_tuner, CMD_SCAN, 200, &direction);
    pthread_mutex_unlock(&stub_tuner->lock);
    return 0;
}

static int tuner_tune(const struct radio_tuner *tuner,
                     unsigned int channel, unsigned int sub_channel)
{
    struct stub_radio_tuner *stub_tuner = (struct stub_radio_tuner *)tuner;

    ALOGI("%s stub_tuner %p channel %d, sub_channel %d",
          __func__, stub_tuner, channel, sub_channel);

    pthread_mutex_lock(&stub_tuner->lock);
    if (channel < stub_tuner->config.lower_limit || channel > stub_tuner->config.upper_limit) {
        pthread_mutex_unlock(&stub_tuner->lock);
        ALOGI("%s channel out of range", __func__);
        return -EINVAL;
    }
    send_command_l(stub_tuner, CMD_TUNE, 100, &channel);
    pthread_mutex_unlock(&stub_tuner->lock);
    return 0;
}

static int tuner_cancel(const struct radio_tuner *tuner)
{
    struct stub_radio_tuner *stub_tuner = (struct stub_radio_tuner *)tuner;

    ALOGI("%s stub_tuner %p", __func__, stub_tuner);

    pthread_mutex_lock(&stub_tuner->lock);
    send_command_l(stub_tuner, CMD_CANCEL, 0, NULL);
    pthread_mutex_unlock(&stub_tuner->lock);
    return 0;
}

static int tuner_get_program_information(const struct radio_tuner *tuner,
                                        radio_program_info_t *info)
{
    struct stub_radio_tuner *stub_tuner = (struct stub_radio_tuner *)tuner;
    int status = 0;
    radio_metadata_t *metadata;

    ALOGI("%s stub_tuner %p", __func__, stub_tuner);
    pthread_mutex_lock(&stub_tuner->lock);
    if (info == NULL) {
        status = -EINVAL;
        goto exit;
    }
    metadata = info->metadata;
    *info = stub_tuner->program;
    info->metadata = metadata;
    if (metadata != NULL && stub_tuner->program.metadata != NULL)
        radio_metadata_add_metadata(&info->metadata, stub_tuner->program.metadata);

exit:
    pthread_mutex_unlock(&stub_tuner->lock);
    return status;
}

static int rdev_get_properties(const struct radio_hw_device *dev,
                                radio_hal_properties_t *properties)
{
    struct stub_radio_device *rdev = (struct stub_radio_device *)dev;

    ALOGI("%s", __func__);
    if (properties == NULL)
        return -EINVAL;
    memcpy(properties, &hw_properties, sizeof(radio_hal_properties_t));
    return 0;
}

static int rdev_open_tuner(const struct radio_hw_device *dev,
                          const radio_hal_band_config_t *config,
                          bool audio,
                          radio_callback_t callback,
                          void *cookie,
                          const struct radio_tuner **tuner)
{
    struct stub_radio_device *rdev = (struct stub_radio_device *)dev;
    int status = 0;

    ALOGI("%s rdev %p", __func__, rdev);
    pthread_mutex_lock(&rdev->lock);

    if (rdev->tuner != NULL) {
        status = -ENOSYS;
        goto exit;
    }

    if (config == NULL || callback == NULL || tuner == NULL) {
        status = -EINVAL;
        goto exit;
    }

    rdev->tuner = (struct stub_radio_tuner *)calloc(1, sizeof(struct stub_radio_tuner));
    if (rdev->tuner == NULL) {
        status = -ENOMEM;
        goto exit;
    }

    rdev->tuner->interface.set_configuration = tuner_set_configuration;
    rdev->tuner->interface.get_configuration = tuner_get_configuration;
    rdev->tuner->interface.scan = tuner_scan;
    rdev->tuner->interface.step = tuner_step;
    rdev->tuner->interface.tune = tuner_tune;
    rdev->tuner->interface.cancel = tuner_cancel;
    rdev->tuner->interface.get_program_information = tuner_get_program_information;

    rdev->tuner->audio = audio;
    rdev->tuner->callback = callback;
    rdev->tuner->cookie = cookie;

    rdev->tuner->dev = rdev;

    pthread_mutex_init(&rdev->tuner->lock, (const pthread_mutexattr_t *) NULL);
    pthread_cond_init(&rdev->tuner->cond, (const pthread_condattr_t *) NULL);
    pthread_create(&rdev->tuner->callback_thread, (const pthread_attr_t *) NULL,
                        callback_thread_loop, rdev->tuner);
    list_init(&rdev->tuner->command_list);

    pthread_mutex_lock(&rdev->tuner->lock);
    send_command_l(rdev->tuner, CMD_CONFIG, 500, (void *)config);
    pthread_mutex_unlock(&rdev->tuner->lock);

    *tuner = &rdev->tuner->interface;

exit:
    pthread_mutex_unlock(&rdev->lock);
    ALOGI("%s DONE", __func__);
    return status;
}

static int rdev_close_tuner(const struct radio_hw_device *dev,
                            const struct radio_tuner *tuner)
{
    struct stub_radio_device *rdev = (struct stub_radio_device *)dev;
    struct stub_radio_tuner *stub_tuner = (struct stub_radio_tuner *)tuner;
    int status = 0;

    ALOGI("%s tuner %p", __func__, tuner);
    pthread_mutex_lock(&rdev->lock);

    if (tuner == NULL) {
        status = -EINVAL;
        goto exit;
    }

    pthread_mutex_lock(&stub_tuner->lock);
    stub_tuner->callback = NULL;
    send_command_l(stub_tuner, CMD_EXIT, 0, NULL);
    pthread_mutex_unlock(&stub_tuner->lock);
    pthread_join(stub_tuner->callback_thread, (void **) NULL);

    if (stub_tuner->program.metadata != NULL)
        radio_metadata_deallocate(stub_tuner->program.metadata);

    free(stub_tuner);
    rdev->tuner = NULL;

exit:
    pthread_mutex_unlock(&rdev->lock);
    return status;
}

static int rdev_close(hw_device_t *device)
{
    struct stub_radio_device *rdev = (struct stub_radio_device *)device;
    if (rdev != NULL) {
        free(rdev->tuner);
    }
    free(rdev);
    return 0;
}

static int rdev_open(const hw_module_t* module, const char* name,
                     hw_device_t** device)
{
    struct stub_radio_device *rdev;
    int ret;

    if (strcmp(name, RADIO_HARDWARE_DEVICE) != 0)
        return -EINVAL;

    rdev = calloc(1, sizeof(struct stub_radio_device));
    if (!rdev)
        return -ENOMEM;

    rdev->device.common.tag = HARDWARE_DEVICE_TAG;
    rdev->device.common.version = RADIO_DEVICE_API_VERSION_1_0;
    rdev->device.common.module = (struct hw_module_t *) module;
    rdev->device.common.close = rdev_close;
    rdev->device.get_properties = rdev_get_properties;
    rdev->device.open_tuner = rdev_open_tuner;
    rdev->device.close_tuner = rdev_close_tuner;

    pthread_mutex_init(&rdev->lock, (const pthread_mutexattr_t *) NULL);

    *device = &rdev->device.common;

    return 0;
}


static struct hw_module_methods_t hal_module_methods = {
    .open = rdev_open,
};

struct radio_module HAL_MODULE_INFO_SYM = {
    .common = {
        .tag = HARDWARE_MODULE_TAG,
        .module_api_version = RADIO_MODULE_API_VERSION_1_0,
        .hal_api_version = HARDWARE_HAL_API_VERSION,
        .id = RADIO_HARDWARE_MODULE_ID,
        .name = "Stub radio HAL",
        .author = "The Android Open Source Project",
        .methods = &hal_module_methods,
    },
};
