/*
 * Copyright (C) 2013 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 requied 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 <dirent.h>
#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <gtest/gtest.h>
#include <linux/ioctl.h>
#define __force
#define __bitwise
#define __user
#include <sound/asound.h>
#include <sys/types.h>
#include <tinyalsa/asoundlib.h>

#define LOG_TAG "pcmtest"
#include <utils/Log.h>
#include <testUtil.h>

#define PCM_PREFIX	"pcm"
#define MIXER_PREFIX	"control"
#define TIMER_PREFIX	"timer"

const char kSoundDir[] = "/dev/snd";

typedef struct PCM_NODE {
    unsigned int card;
    unsigned int device;
    unsigned int flags;
} pcm_node_t;

static pcm_node_t *pcmnodes;

static unsigned int pcms;
static unsigned int cards;
static unsigned int mixers;
static unsigned int timers;

unsigned int getPcmNodes(void)
{
    DIR *d;
    struct dirent *de;
    unsigned int pcount = 0;

    d = opendir(kSoundDir);
    if (d == 0)
        return 0;
    while ((de = readdir(d)) != NULL) {
        if (de->d_name[0] == '.')
            continue;
        if (strstr(de->d_name, PCM_PREFIX))
            pcount++;
    }
    closedir(d);
    return pcount;
}

int getSndDev(unsigned int pcmdevs)
{
    DIR *d;
    struct dirent *de;
    unsigned int prevcard = -1;

    d = opendir(kSoundDir);
    if (d == 0)
        return -ENXIO;
    pcmnodes = (pcm_node_t *)malloc(pcmdevs * sizeof(pcm_node_t));
    if (!pcmnodes)
        return -ENOMEM;
    pcms = 0;
    while ((de = readdir(d)) != NULL) {
        if (de->d_name[0] == '.')
            continue;
        /* printf("%s\n", de->d_name); */
        if (strstr(de->d_name, PCM_PREFIX)) {
            char flags;

            EXPECT_LE(pcms, pcmdevs) << "Too many PCMs";
            if (pcms >= pcmdevs)
                continue;
            sscanf(de->d_name, PCM_PREFIX "C%uD%u", &(pcmnodes[pcms].card),
                   &(pcmnodes[pcms].device));
            flags = de->d_name[strlen(de->d_name)-1];
            if (flags == 'c') {
                pcmnodes[pcms].flags = PCM_IN;
            } else if(flags == 'p') {
                pcmnodes[pcms].flags = PCM_OUT;
            } else {
                pcmnodes[pcms].flags = -1;
                testPrintI("Unknown PCM type = %c", flags);
            }
            if (prevcard != pcmnodes[pcms].card)
                cards++;
            prevcard = pcmnodes[pcms].card;
            pcms++;
            continue;
        }
        if (strstr(de->d_name, MIXER_PREFIX)) {
            unsigned int mixer = -1;
            sscanf(de->d_name, MIXER_PREFIX "C%u", &mixer);
            mixers++;
            continue;
        }
        if (strstr(de->d_name, TIMER_PREFIX)) {
            timers++;
            continue;
        }
    }
    closedir(d);
    return 0;
}

int getPcmParams(unsigned int i)
{
    struct pcm_params *params;
    unsigned int min;
    unsigned int max;

    params = pcm_params_get(pcmnodes[i].card, pcmnodes[i].device,
                            pcmnodes[i].flags);
    if (params == NULL)
        return -ENODEV;

    min = pcm_params_get_min(params, PCM_PARAM_RATE);
    max = pcm_params_get_max(params, PCM_PARAM_RATE);
    EXPECT_LE(min, max);
    /* printf("        Rate:\tmin=%uHz\tmax=%uHz\n", min, max); */
    min = pcm_params_get_min(params, PCM_PARAM_CHANNELS);
    max = pcm_params_get_max(params, PCM_PARAM_CHANNELS);
    EXPECT_LE(min, max);
    /* printf("    Channels:\tmin=%u\t\tmax=%u\n", min, max); */
    min = pcm_params_get_min(params, PCM_PARAM_SAMPLE_BITS);
    max = pcm_params_get_max(params, PCM_PARAM_SAMPLE_BITS);
    EXPECT_LE(min, max);
    /* printf(" Sample bits:\tmin=%u\t\tmax=%u\n", min, max); */
    min = pcm_params_get_min(params, PCM_PARAM_PERIOD_SIZE);
    max = pcm_params_get_max(params, PCM_PARAM_PERIOD_SIZE);
    EXPECT_LE(min, max);
    /* printf(" Period size:\tmin=%u\t\tmax=%u\n", min, max); */
    min = pcm_params_get_min(params, PCM_PARAM_PERIODS);
    max = pcm_params_get_max(params, PCM_PARAM_PERIODS);
    EXPECT_LE(min, max);
    /* printf("Period count:\tmin=%u\t\tmax=%u\n", min, max); */

    pcm_params_free(params);
    return 0;
}

TEST(pcmtest, CheckAudioDir) {
    pcms = getPcmNodes();
    ASSERT_GT(pcms, 0U);
}

TEST(pcmtest, GetSoundDevs) {
    int err = getSndDev(pcms);
    testPrintI(" DEVICES = PCMS:%u CARDS:%u MIXERS:%u TIMERS:%u",
               pcms, cards, mixers, timers);
    ASSERT_EQ(0, err);
}

TEST(pcmtest, CheckPcmSanity0) {
    ASSERT_NE(0U, pcms);
}

TEST(pcmtest, CheckPcmSanity1) {
    EXPECT_NE(1U, pcms % 2);
}

TEST(pcmtests, CheckMixerSanity) {
    ASSERT_NE(0U, mixers);
    ASSERT_EQ(mixers, cards);
}

TEST(pcmtest, CheckTimesSanity0) {
    ASSERT_NE(0U, timers);
}

TEST(pcmtest, CheckTimesSanity1) {
    EXPECT_EQ(1U, timers);
}

TEST(pcmtest, CheckPcmDevices) {
    for (unsigned int i = 0; i < pcms; i++) {
        EXPECT_EQ(0, getPcmParams(i));
    }
    free(pcmnodes);
}

TEST(pcmtest, CheckMixerDevices) {
    struct mixer *mixer;
    for (unsigned int i = 0; i < mixers; i++) {
         mixer = mixer_open(i);
         EXPECT_TRUE(mixer != NULL);
         if (mixer)
             mixer_close(mixer);
    }
}

TEST(pcmtest, CheckTimer) {
    int ver = 0;
    int fd = open("/dev/snd/timer", O_RDWR | O_NONBLOCK);
    ASSERT_GE(fd, 0);
    int ret = ioctl(fd, SNDRV_TIMER_IOCTL_PVERSION, &ver);
    EXPECT_EQ(0, ret);
    testPrintI(" Timer Version = 0x%x", ver);
    close(fd);
}
