/*
 * Copyright (C) 2016 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 "ConsumerIrHal"

#include <cutils/log.h>
#include <errno.h>
#include <fcntl.h>
#include <hardware/hardware.h>
#include <hardware/consumerir.h>
#include <malloc.h>
#include <pthread.h>
#include <stdbool.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

#include <samsung_consumerir.h>

#define ARRAY_SIZE(a) (sizeof(a) / sizeof(a[0]))
#define UNUSED __attribute__((unused))

static int fd = 0;
static pthread_mutex_t g_mtx;

static bool try_append_number(char *buffer, int *len, int size, int number)
{
    int stored;

    stored = snprintf(&buffer[*len], size - *len, "%d,", number);

    if (stored < 0 || stored >= (size - *len))
        return false;

    *len += stored;
    return true;
}

static bool grow_buffer(char **buffer, int *size)
{
    char *new_buffer;

    *size *= 2;
    new_buffer = realloc(*buffer, *size);
    if (new_buffer == NULL)
        return false;

    *buffer = new_buffer;
    return true;
}

static bool append_number(char **buffer, int *len, int *size, int number)
{
    if (try_append_number(*buffer, len, *size, number))
        return true;

    if (!grow_buffer(buffer, size))
        return false;

    return try_append_number(*buffer, len, *size, number);
}

static int consumerir_transmit(UNUSED struct consumerir_device *dev,
   int carrier_freq, const int pattern[], int pattern_len)
{
    int buffer_len = 0;
    int buffer_size = 128;
    int i;
    float factor;
    char *buffer;

    pthread_mutex_lock(&g_mtx);

    buffer = malloc(buffer_size);
    if (buffer == NULL)
        return -ENOMEM;

    // Write the header
    if (!append_number(&buffer, &buffer_len, &buffer_size, carrier_freq))
        goto error;

#ifndef MS_IR_SIGNAL
    // Calculate factor of conversion from microseconds to pulses
    factor = 1000000 / carrier_freq;
#else
    factor = 1;
#endif

    // Write out the timing pattern
    for (i = 0; i < pattern_len; i++) {
        if (!append_number(&buffer, &buffer_len, &buffer_size,
                (int) (pattern[i] / factor)))
            goto error;
    }

    buffer[buffer_len - 1] = 0;
    write(fd, buffer, buffer_len - 1);

    free(buffer);

    pthread_mutex_unlock(&g_mtx);

    return 0;

error:
    free(buffer);
    return -ENOMEM;
}

static int consumerir_get_num_carrier_freqs(UNUSED struct consumerir_device *dev)
{
    return ARRAY_SIZE(consumerir_freqs);
}

static int consumerir_get_carrier_freqs(struct consumerir_device *dev,
    size_t len, consumerir_freq_range_t *ranges)
{
    size_t to_copy = consumerir_get_num_carrier_freqs(dev);

    to_copy = len < to_copy ? len : to_copy;
    memcpy(ranges, consumerir_freqs, to_copy * sizeof(consumerir_freq_range_t));
    return to_copy;
}

static int consumerir_close(hw_device_t *dev)
{
    free(dev);
    close(fd);
    pthread_mutex_destroy(&g_mtx);
    return 0;
}

/*
 * Generic device handling
 */
static int consumerir_open(const hw_module_t *module, const char *name,
        hw_device_t **device)
{
    if (strcmp(name, CONSUMERIR_TRANSMITTER) != 0)
        return -EINVAL;

    if (device == NULL) {
        ALOGE("NULL device on open");
        return -EINVAL;
    }

    consumerir_device_t *dev = malloc(sizeof(consumerir_device_t));
    memset(dev, 0, sizeof(consumerir_device_t));

    dev->common.tag            = HARDWARE_DEVICE_TAG;
    dev->common.tag            = HARDWARE_DEVICE_TAG;
    dev->common.version        = 0;
    dev->common.module         = (struct hw_module_t*) module;
    dev->common.close          = consumerir_close;

    dev->transmit              = consumerir_transmit;
    dev->get_carrier_freqs     = consumerir_get_carrier_freqs;
    dev->get_num_carrier_freqs = consumerir_get_num_carrier_freqs;

    pthread_mutex_init(&g_mtx, NULL);

    *device = (hw_device_t*) dev;
    fd = open(IR_PATH, O_RDWR);
    return fd;
}

static struct hw_module_methods_t consumerir_module_methods = {
    .open = consumerir_open,
};

consumerir_module_t HAL_MODULE_INFO_SYM = {
    .common = {
        .tag                = HARDWARE_MODULE_TAG,
        .module_api_version = CONSUMERIR_MODULE_API_VERSION_1_0,
        .hal_api_version    = HARDWARE_HAL_API_VERSION,
        .id                 = CONSUMERIR_HARDWARE_MODULE_ID,
        .name               = "Consumer IR Module",
        .author             = "The CyanogenMod Project",
        .methods            = &consumerir_module_methods,
    },
};
