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

#include <mutex>
#include <log/log.h>
#include "talsa.h"
#include "debug.h"

namespace android {
namespace hardware {
namespace audio {
namespace V7_0 {
namespace implementation {
namespace talsa {

namespace {

struct mixer *gMixer0 = nullptr;
int gMixerRefcounter0 = 0;
std::mutex gMixerMutex;

void mixerSetValueAll(struct mixer_ctl *ctl, int value) {
    const unsigned int n = mixer_ctl_get_num_values(ctl);
    for (unsigned int i = 0; i < n; i++) {
        ::mixer_ctl_set_value(ctl, i, value);
    }
}

void mixerSetPercentAll(struct mixer_ctl *ctl, int percent) {
    const unsigned int n = mixer_ctl_get_num_values(ctl);
    for (unsigned int i = 0; i < n; i++) {
        ::mixer_ctl_set_percent(ctl, i, percent);
    }
}

struct mixer *mixerGetOrOpenImpl(const unsigned card,
                                 struct mixer *&gMixer,
                                 int &refcounter) {
    if (!gMixer) {
        struct mixer *mixer = ::mixer_open(card);
        if (!mixer) {
            return FAILURE(nullptr);
        }

        mixerSetPercentAll(::mixer_get_ctl_by_name(mixer, "Master Playback Volume"), 100);
        mixerSetPercentAll(::mixer_get_ctl_by_name(mixer, "Capture Volume"), 100);

        mixerSetValueAll(::mixer_get_ctl_by_name(mixer, "Master Playback Switch"), 1);
        mixerSetValueAll(::mixer_get_ctl_by_name(mixer, "Capture Switch"), 1);

        gMixer = mixer;
    }

    ++refcounter;
    return gMixer;
}

struct mixer *mixerGetOrOpen(const unsigned card) {
    std::lock_guard<std::mutex> guard(gMixerMutex);

    switch (card) {
    case 0:  return mixerGetOrOpenImpl(card, gMixer0, gMixerRefcounter0);
    default: return FAILURE(nullptr);
    }
}

bool mixerUnrefImpl(struct mixer *mixer, struct mixer *&gMixer, int &refcounter) {
    if (mixer == gMixer) {
        if (0 == --refcounter) {
            ::mixer_close(mixer);
            gMixer = nullptr;
        }
        return true;
    } else {
        return false;
    }
}

bool mixerUnref(struct mixer *mixer) {
    std::lock_guard<std::mutex> guard(gMixerMutex);

    return mixerUnrefImpl(mixer, gMixer0, gMixerRefcounter0);
}

}  // namespace

void PcmDeleter::operator()(pcm_t *x) const {
    LOG_ALWAYS_FATAL_IF(::pcm_close(x) != 0);
};

std::unique_ptr<pcm_t, PcmDeleter> pcmOpen(const unsigned int dev,
                                           const unsigned int card,
                                           const unsigned int nChannels,
                                           const size_t sampleRateHz,
                                           const size_t frameCount,
                                           const bool isOut) {
    struct pcm_config pcm_config;
    memset(&pcm_config, 0, sizeof(pcm_config));

    pcm_config.channels = nChannels;
    pcm_config.rate = sampleRateHz;
    pcm_config.period_size = frameCount;     // Approx frames between interrupts
    pcm_config.period_count = 8;             // Approx interrupts per buffer
    pcm_config.format = PCM_FORMAT_S16_LE;
    pcm_config.start_threshold = 0;
    pcm_config.stop_threshold = isOut ? 0 : INT_MAX;

    PcmPtr pcm =
        PcmPtr(::pcm_open(dev, card,
                          (isOut ? PCM_OUT : PCM_IN) | PCM_MONOTONIC,
                           &pcm_config));
    if (::pcm_is_ready(pcm.get())) {
        return pcm;
    } else {
        ALOGE("%s:%d pcm_open failed for nChannels=%u sampleRateHz=%zu "
              "frameCount=%zu isOut=%d with %s", __func__, __LINE__,
              nChannels, sampleRateHz, frameCount, isOut,
              pcm_get_error(pcm.get()));
        return FAILURE(nullptr);
    }
}

Mixer::Mixer(unsigned card): mMixer(mixerGetOrOpen(card)) {}

Mixer::~Mixer() {
    if (mMixer) {
        LOG_ALWAYS_FATAL_IF(!mixerUnref(mMixer));
    }
}

}  // namespace talsa
}  // namespace implementation
}  // namespace V7_0
}  // namespace audio
}  // namespace hardware
}  // namespace android
