/*
 * Copyright (C) 2013 The Android Open Source Project
 * Inspired by TinyHW, written by Mark Brown at Wolfson Micro
 *
 * 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 "audio_route"
/*#define LOG_NDEBUG 0*/

#include <errno.h>
#include <expat.h>
#include <stdbool.h>
#include <stdio.h>
#include <string.h>

#include <cutils/log.h>

#include <tinyalsa/asoundlib.h>

#define BUF_SIZE 1024
#define MIXER_XML_PATH "/system/etc/mixer_paths.xml"
#define INITIAL_MIXER_PATH_SIZE 8

struct mixer_state {
    struct mixer_ctl *ctl;
    unsigned int num_values;
    int *old_value;
    int *new_value;
    int *reset_value;
    /* If linked is true, only the first element in each array is valid */
    bool old_linked;
    bool new_linked;
    bool reset_linked;
};

struct mixer_setting {
    struct mixer_ctl *ctl;
    unsigned int num_values;
    int *value;
    /* If linked is true, only the first element in each array is valid */
    bool linked;
};

struct mixer_value {
    struct mixer_ctl *ctl;
    int index;
    int value;
};

struct mixer_path {
    char *name;
    unsigned int size;
    unsigned int length;
    struct mixer_setting *setting;
};

struct audio_route {
    struct mixer *mixer;
    unsigned int num_mixer_ctls;
    struct mixer_state *mixer_state;

    unsigned int mixer_path_size;
    unsigned int num_mixer_paths;
    struct mixer_path *mixer_path;
};

struct config_parse_state {
    struct audio_route *ar;
    struct mixer_path *path;
    int level;
};

/* path functions */

static void path_print(struct mixer_path *path)
{
    unsigned int i;
    unsigned int j;

    ALOGE("Path: %s, length: %d", path->name, path->length);
    for (i = 0; i < path->length; i++) {
        ALOGE("  id=%d: ctl=%s linked=%c", i,
              mixer_ctl_get_name(path->setting[i].ctl),
              path->setting[i].linked ? 'y' : 'n');
        for (j = 0; j < path->setting[i].num_values; j++)
            ALOGE("    id=%d value=%d", j, path->setting[i].value[j]);
    }
}

static void path_free(struct audio_route *ar)
{
    unsigned int i;

    for (i = 0; i < ar->num_mixer_paths; i++) {
        if (ar->mixer_path[i].name)
            free(ar->mixer_path[i].name);
        if (ar->mixer_path[i].setting) {
            if (ar->mixer_path[i].setting->value)
                free(ar->mixer_path[i].setting->value);
            free(ar->mixer_path[i].setting);
        }
    }
    free(ar->mixer_path);
}

static struct mixer_path *path_get_by_name(struct audio_route *ar,
                                           const char *name)
{
    unsigned int i;

    for (i = 0; i < ar->num_mixer_paths; i++)
        if (strcmp(ar->mixer_path[i].name, name) == 0)
            return &ar->mixer_path[i];

    return NULL;
}

static struct mixer_path *path_create(struct audio_route *ar, const char *name)
{
    struct mixer_path *new_mixer_path = NULL;

    if (path_get_by_name(ar, name)) {
        ALOGE("Path name '%s' already exists", name);
        return NULL;
    }

    /* check if we need to allocate more space for mixer paths */
    if (ar->mixer_path_size <= ar->num_mixer_paths) {
        if (ar->mixer_path_size == 0)
            ar->mixer_path_size = INITIAL_MIXER_PATH_SIZE;
        else
            ar->mixer_path_size *= 2;

        new_mixer_path = realloc(ar->mixer_path, ar->mixer_path_size *
                                 sizeof(struct mixer_path));
        if (new_mixer_path == NULL) {
            ALOGE("Unable to allocate more paths");
            return NULL;
        } else {
            ar->mixer_path = new_mixer_path;
        }
    }

    /* initialise the new mixer path */
    ar->mixer_path[ar->num_mixer_paths].name = strdup(name);
    ar->mixer_path[ar->num_mixer_paths].size = 0;
    ar->mixer_path[ar->num_mixer_paths].length = 0;
    ar->mixer_path[ar->num_mixer_paths].setting = NULL;

    /* return the mixer path just added, then increment number of them */
    return &ar->mixer_path[ar->num_mixer_paths++];
}

static int find_ctl_in_path(struct mixer_path *path, struct mixer_ctl *ctl)
{
    unsigned int i;

    for (i = 0; i < path->length; i++)
        if (path->setting[i].ctl == ctl)
            return i;

    return -1;
}

static int alloc_path_setting(struct mixer_path *path)
{
    struct mixer_setting *new_path_setting;
    int path_index;

    /* check if we need to allocate more space for path settings */
    if (path->size <= path->length) {
        if (path->size == 0)
            path->size = INITIAL_MIXER_PATH_SIZE;
        else
            path->size *= 2;

        new_path_setting = realloc(path->setting,
                                   path->size * sizeof(struct mixer_setting));
        if (new_path_setting == NULL) {
            ALOGE("Unable to allocate more path settings");
            return -1;
        } else {
            path->setting = new_path_setting;
        }
    }

    path_index = path->length;
    path->length++;

    return path_index;
}

static int path_add_setting(struct mixer_path *path,
                            struct mixer_setting *setting)
{
    unsigned int i;
    int path_index;

    if (find_ctl_in_path(path, setting->ctl) != -1) {
        ALOGE("Control '%s' already exists in path '%s'",
              mixer_ctl_get_name(setting->ctl), path->name);
        return -1;
    }

    path_index = alloc_path_setting(path);
    if (path_index < 0)
        return -1;

    path->setting[path_index].ctl = setting->ctl;
    path->setting[path_index].num_values = setting->num_values;
    path->setting[path_index].value = malloc(setting->num_values * sizeof(int));
    path->setting[path_index].linked = setting->linked;
    if (setting->linked) {
        path->setting[path_index].value[0] = setting->value[0];
    } else {
        for (i = 0; i < setting->num_values; i++)
            path->setting[path_index].value[i] = setting->value[i];
    }

    return 0;
}

static int path_add_value(struct mixer_path *path,
                          struct mixer_value *mixer_value)
{
    unsigned int i;
    int path_index;
    unsigned int num_values;

    /* Check that mixer value index is within range */
    num_values = mixer_ctl_get_num_values(mixer_value->ctl);
    if (mixer_value->index >= (int)num_values) {
        ALOGE("mixer index %d is out of range for '%s'", mixer_value->index,
              mixer_ctl_get_name(mixer_value->ctl));
        return -1;
    }

    path_index = find_ctl_in_path(path, mixer_value->ctl);
    if (path_index < 0) {
        /* New path */

        path_index = alloc_path_setting(path);
        if (path_index < 0)
            return -1;

        /* initialise the new path setting */
        path->setting[path_index].ctl = mixer_value->ctl;
        path->setting[path_index].num_values = num_values;
        path->setting[path_index].value = malloc(num_values * sizeof(int));
        path->setting[path_index].linked = true;
        path->setting[path_index].value[0] = mixer_value->value;
    }

    if (mixer_value->index == -1) {
        /* Linked, so only set the first value */
        path->setting[path_index].linked = true;
        path->setting[path_index].value[0] = mixer_value->value;
    } else {
        if (path->setting[path_index].linked && (num_values > 1)) {
            /* Unlinking the values, so duplicate them across */
            for (i = 1; i < num_values; i++) {
                path->setting[path_index].value[i] =
                        path->setting[path_index].value[0];
            }
            path->setting[path_index].linked = false;
        }
        path->setting[path_index].value[mixer_value->index] = mixer_value->value;
    }

    return 0;
}

static int path_add_path(struct mixer_path *path, struct mixer_path *sub_path)
{
    unsigned int i;

    for (i = 0; i < sub_path->length; i++)
        if (path_add_setting(path, &sub_path->setting[i]) < 0)
            return -1;

    return 0;
}

static int path_apply(struct audio_route *ar, struct mixer_path *path)
{
    unsigned int i;
    unsigned int j;
    unsigned int ctl_index;

    for (i = 0; i < path->length; i++) {
        struct mixer_ctl *ctl = path->setting[i].ctl;

        /* locate the mixer ctl in the list */
        for (ctl_index = 0; ctl_index < ar->num_mixer_ctls; ctl_index++)
            if (ar->mixer_state[ctl_index].ctl == ctl)
                break;

        /* apply the new value(s) */
        for (j = 0; j < ar->mixer_state[ctl_index].num_values; j++) {
            ar->mixer_state[ctl_index].new_value[j] = path->setting[i].value[j];
            if (path->setting[i].linked)
                break;
        }
        ar->mixer_state[ctl_index].new_linked = path->setting[i].linked;
    }

    return 0;
}

/* mixer helper function */
static int mixer_enum_string_to_value(struct mixer_ctl *ctl, const char *string)
{
    unsigned int i;

    /* Search the enum strings for a particular one */
    for (i = 0; i < mixer_ctl_get_num_enums(ctl); i++) {
        if (strcmp(mixer_ctl_get_enum_string(ctl, i), string) == 0)
            break;
    }

    return i;
}

static void start_tag(void *data, const XML_Char *tag_name,
                      const XML_Char **attr)
{
    const XML_Char *attr_name = NULL;
    const XML_Char *attr_id = NULL;
    const XML_Char *attr_value = NULL;
    struct config_parse_state *state = data;
    struct audio_route *ar = state->ar;
    unsigned int i;
    unsigned int ctl_index;
    struct mixer_ctl *ctl;
    int value;
    unsigned int id;
    struct mixer_value mixer_value;

    /* Get name, id and value attributes (these may be empty) */
    for (i = 0; attr[i]; i += 2) {
        if (strcmp(attr[i], "name") == 0)
            attr_name = attr[i + 1];
        if (strcmp(attr[i], "id") == 0)
            attr_id = attr[i + 1];
        else if (strcmp(attr[i], "value") == 0)
            attr_value = attr[i + 1];
    }

    /* Look at tags */
    if (strcmp(tag_name, "path") == 0) {
        if (attr_name == NULL) {
            ALOGE("Unnamed path!");
        } else {
            if (state->level == 1) {
                /* top level path: create and stash the path */
                state->path = path_create(ar, (char *)attr_name);
            } else {
                /* nested path */
                struct mixer_path *sub_path = path_get_by_name(ar, attr_name);
                path_add_path(state->path, sub_path);
            }
        }
    }

    else if (strcmp(tag_name, "ctl") == 0) {
        /* Obtain the mixer ctl and value */
        ctl = mixer_get_ctl_by_name(ar->mixer, attr_name);
        switch (mixer_ctl_get_type(ctl)) {
        case MIXER_CTL_TYPE_BOOL:
        case MIXER_CTL_TYPE_INT:
            value = atoi((char *)attr_value);
            break;
        case MIXER_CTL_TYPE_ENUM:
            value = mixer_enum_string_to_value(ctl, (char *)attr_value);
            break;
        default:
            value = 0;
            break;
        }

        if (state->level == 1) {
            /* top level ctl (initial setting) */

            /* locate the mixer ctl in the list */
            for (ctl_index = 0; ctl_index < ar->num_mixer_ctls; ctl_index++) {
                if (ar->mixer_state[ctl_index].ctl == ctl)
                    break;
            }

            /* apply the new value */
            if (attr_id) {
                /* set only one value */
                id = atoi((char *)attr_id);
                if (id < ar->mixer_state[ctl_index].num_values) {
                    if (ar->mixer_state[ctl_index].new_linked) {
                        /*
                         * We're unlinking the values, so copy old_value[0] into
                         * all the new_value elements.
                         */
                        for (i = 0; i < ar->mixer_state[ctl_index].num_values; i++) {
                            ar->mixer_state[ctl_index].new_value[i] =
                                    ar->mixer_state[ctl_index].old_value[0];
                        }
                        ar->mixer_state[ctl_index].new_linked = false;
                    }
                    ar->mixer_state[ctl_index].new_value[id] = value;
                } else {
                    ALOGE("value id out of range for mixer ctl '%s'",
                          mixer_ctl_get_name(ctl));
                }
            } else {
                ar->mixer_state[ctl_index].new_value[0] = value;
                ar->mixer_state[ctl_index].new_linked = true;
            }
        } else {
            /* nested ctl (within a path) */
            mixer_value.ctl = ctl;
            mixer_value.value = value;
            if (attr_id)
                mixer_value.index = atoi((char *)attr_id);
            else
                mixer_value.index = -1;
            path_add_value(state->path, &mixer_value);
        }
    }

    state->level++;
}

static void end_tag(void *data, const XML_Char *tag_name)
{
    struct config_parse_state *state = data;

    state->level--;
}

static int alloc_mixer_state(struct audio_route *ar)
{
    unsigned int i;
    unsigned int j;
    unsigned int num_values;
    struct mixer_ctl *ctl;
    bool linked;

    ar->num_mixer_ctls = mixer_get_num_ctls(ar->mixer);
    ar->mixer_state = malloc(ar->num_mixer_ctls * sizeof(struct mixer_state));
    if (!ar->mixer_state)
        return -1;

    for (i = 0; i < ar->num_mixer_ctls; i++) {
        ctl = mixer_get_ctl(ar->mixer, i);
        num_values = mixer_ctl_get_num_values(ctl);

        ar->mixer_state[i].old_value = malloc(num_values * sizeof(int));
        ar->mixer_state[i].new_value = malloc(num_values * sizeof(int));
        ar->mixer_state[i].reset_value = malloc(num_values * sizeof(int));

        /*
         * Get all mixer values for controls with multiple values. If all
         * values are the same, set the linked flag.
         */
        linked = true;
        for (j = 0; j < num_values; j++) {
            ar->mixer_state[i].old_value[j] = mixer_ctl_get_value(ctl, j);
            ar->mixer_state[i].new_value[j] = ar->mixer_state[i].old_value[j];

            /*
             * If the next value is different from the last, set linked to
             * false.
             */
            if ((j > 0) && (ar->mixer_state[i].old_value[j - 1] !=
                            ar->mixer_state[i].old_value[j])) {
                linked = false;
            }
        }
        ar->mixer_state[i].ctl = ctl;
        ar->mixer_state[i].old_linked = linked;
        ar->mixer_state[i].new_linked = linked;
        ar->mixer_state[i].num_values = num_values;
    }

    return 0;
}

static void free_mixer_state(struct audio_route *ar)
{
    unsigned int i;

    for (i = 0; i < ar->num_mixer_ctls; i++) {
        free(ar->mixer_state[i].old_value);
        free(ar->mixer_state[i].new_value);
        free(ar->mixer_state[i].reset_value);
    }

    free(ar->mixer_state);
    ar->mixer_state = NULL;
}

/* Update the mixer with any changed values */
int audio_route_update_mixer(struct audio_route *ar)
{
    unsigned int i;
    unsigned int j;

    for (i = 0; i < ar->num_mixer_ctls; i++) {
        unsigned int num_values = ar->mixer_state[i].num_values;

        /* if the value has changed, update the mixer */
        if (ar->mixer_state[i].new_linked) {
            if (ar->mixer_state[i].old_value[0] != ar->mixer_state[i].new_value[0]) {
                /* linked ctl, so set all ctl values the same */
                for (j = 0; j < num_values; j++)
                    mixer_ctl_set_value(ar->mixer_state[i].ctl, j,
                                        ar->mixer_state[i].new_value[0]);
                ar->mixer_state[i].old_value[0] = ar->mixer_state[i].new_value[0];
            }
        } else {
            for (j = 0; j < num_values; j++) {
                /*
                 * unlinked ctl, so set each value if necessary.
                 * Note that if the new value is unlinked but the old is
                 * linked, only value 0 is valid, so we always have to
                 * update the mixer for the other values.
                 */
                if (ar->mixer_state[i].old_linked ||
                    (ar->mixer_state[i].old_value[j] !=
                            ar->mixer_state[i].new_value[j])) {
                    mixer_ctl_set_value(ar->mixer_state[i].ctl, j,
                                        ar->mixer_state[i].new_value[j]);
                    ar->mixer_state[i].old_value[j] = ar->mixer_state[i].new_value[j];
                }
            }
        }
        ar->mixer_state[i].old_linked = ar->mixer_state[i].new_linked;
    }

    return 0;
}

/* saves the current state of the mixer, for resetting all controls */
static void save_mixer_state(struct audio_route *ar)
{
    unsigned int i;
    unsigned int j;

    for (i = 0; i < ar->num_mixer_ctls; i++) {
        for (j = 0; j < ar->mixer_state[i].num_values; j++) {
            ar->mixer_state[i].reset_value[j] = ar->mixer_state[i].new_value[j];

            /* if the values are linked, only need to save value 0 */
            if (ar->mixer_state[i].new_linked)
                break;
        }
        ar->mixer_state[i].reset_linked = ar->mixer_state[i].new_linked;
    }
}

/* Reset the audio routes back to the initial state */
void audio_route_reset(struct audio_route *ar)
{
    unsigned int i;
    unsigned int j;

    /* load all of the saved values */
    for (i = 0; i < ar->num_mixer_ctls; i++) {
        for (j = 0; j < ar->mixer_state[i].num_values; j++) {
            ar->mixer_state[i].new_value[j] = ar->mixer_state[i].reset_value[j];

            /* if the values are linked, only need to save value 0 */
            if (ar->mixer_state[i].reset_linked)
                break;
        }
        ar->mixer_state[i].new_linked = ar->mixer_state[i].reset_linked;
    }
}

/* Apply an audio route path by name */
int audio_route_apply_path(struct audio_route *ar, const char *name)
{
    struct mixer_path *path;

    if (!ar) {
        ALOGE("invalid audio_route");
        return -1;
    }

    path = path_get_by_name(ar, name);
    if (!path) {
        ALOGE("unable to find path '%s'", name);
        return -1;
    }

    path_apply(ar, path);

    return 0;
}

struct audio_route *audio_route_init(unsigned int card, const char *xml_path)
{
    struct config_parse_state state;
    XML_Parser parser;
    FILE *file;
    int bytes_read;
    void *buf;
    int i;
    struct audio_route *ar;

    ar = calloc(1, sizeof(struct audio_route));
    if (!ar)
        goto err_calloc;

    ar->mixer = mixer_open(card);
    if (!ar->mixer) {
        ALOGE("Unable to open the mixer, aborting.");
        goto err_mixer_open;
    }

    ar->mixer_path = NULL;
    ar->mixer_path_size = 0;
    ar->num_mixer_paths = 0;

    /* allocate space for and read current mixer settings */
    if (alloc_mixer_state(ar) < 0)
        goto err_mixer_state;

    /* use the default XML path if none is provided */
    if (xml_path == NULL)
        xml_path = MIXER_XML_PATH;

    file = fopen(xml_path, "r");

    if (!file) {
        ALOGE("Failed to open %s", xml_path);
        goto err_fopen;
    }

    parser = XML_ParserCreate(NULL);
    if (!parser) {
        ALOGE("Failed to create XML parser");
        goto err_parser_create;
    }

    memset(&state, 0, sizeof(state));
    state.ar = ar;
    XML_SetUserData(parser, &state);
    XML_SetElementHandler(parser, start_tag, end_tag);

    for (;;) {
        buf = XML_GetBuffer(parser, BUF_SIZE);
        if (buf == NULL)
            goto err_parse;

        bytes_read = fread(buf, 1, BUF_SIZE, file);
        if (bytes_read < 0)
            goto err_parse;

        if (XML_ParseBuffer(parser, bytes_read,
                            bytes_read == 0) == XML_STATUS_ERROR) {
            ALOGE("Error in mixer xml (%s)", MIXER_XML_PATH);
            goto err_parse;
        }

        if (bytes_read == 0)
            break;
    }

    /* apply the initial mixer values, and save them so we can reset the
       mixer to the original values */
    audio_route_update_mixer(ar);
    save_mixer_state(ar);

    XML_ParserFree(parser);
    fclose(file);
    return ar;

err_parse:
    XML_ParserFree(parser);
err_parser_create:
    fclose(file);
err_fopen:
    free_mixer_state(ar);
err_mixer_state:
    mixer_close(ar->mixer);
err_mixer_open:
    free(ar);
    ar = NULL;
err_calloc:
    return NULL;
}

void audio_route_free(struct audio_route *ar)
{
    free_mixer_state(ar);
    mixer_close(ar->mixer);
    free(ar);
}
