// Copyright 2017 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include <audio-utils/audio-device-stream.h>
#include <audio-utils/audio-input.h>
#include <audio-utils/audio-output.h>
#include <fcntl.h>
#include <inttypes.h>
#include <zircon/assert.h>
#include <zircon/device/audio.h>
#include <zircon/process.h>
#include <zircon/syscalls.h>
#include <zx/channel.h>
#include <zx/handle.h>
#include <zx/vmo.h>
#include <fbl/algorithm.h>
#include <fbl/auto_call.h>
#include <fbl/limits.h>
#include <fdio/io.h>
#include <stdio.h>
#include <string.h>

namespace audio {
namespace utils {

static constexpr zx_duration_t CALL_TIMEOUT = ZX_MSEC(500);
template <typename ReqType, typename RespType>
zx_status_t DoCallImpl(const zx::channel& channel,
                       const ReqType&     req,
                       RespType*          resp,
                       zx::handle*        resp_handle_out,
                       uint32_t*          resp_len_out = nullptr) {
    zx_channel_call_args_t args;

    ZX_DEBUG_ASSERT((resp_handle_out == nullptr) || !resp_handle_out->is_valid());

    args.wr_bytes       = const_cast<ReqType*>(&req);
    args.wr_num_bytes   = sizeof(ReqType);
    args.wr_handles     = nullptr;
    args.wr_num_handles = 0;
    args.rd_bytes       = resp;
    args.rd_num_bytes   = sizeof(RespType);
    args.rd_handles     = resp_handle_out ? resp_handle_out->reset_and_get_address() : nullptr;
    args.rd_num_handles = resp_handle_out ? 1 : 0;

    uint32_t bytes, handles;
    zx_status_t read_status, write_status;

    write_status = channel.call(0, zx_deadline_after(CALL_TIMEOUT), &args, &bytes, &handles,
                                &read_status);

    if (write_status != ZX_OK) {
        if (write_status == ZX_ERR_CALL_FAILED) {
            printf("Cmd read failure (cmd %04x, res %d)\n", req.hdr.cmd, read_status);
            return read_status;
        } else {
            printf("Cmd write failure (cmd %04x, res %d)\n", req.hdr.cmd, write_status);
            return write_status;
        }
    }

    // If the caller wants to know the size of the response length, let them
    // check to make sure it is consistent with what they expect.  Otherwise,
    // make sure that the number of bytes we got back matches the size of the
    // response structure.
    if (resp_len_out != nullptr) {
        *resp_len_out = bytes;
    } else
    if (bytes != sizeof(RespType)) {
        printf("Unexpected response size (got %u, expected %zu)\n", bytes, sizeof(RespType));
        return ZX_ERR_INTERNAL;
    }

    return ZX_OK;
}

template <typename ReqType, typename RespType>
zx_status_t DoCall(const zx::channel& channel,
                   const ReqType&     req,
                   RespType*          resp,
                   zx::handle*        resp_handle_out = nullptr) {
    zx_status_t res = DoCallImpl(channel, req, resp, resp_handle_out);
    return (res != ZX_OK) ? res : resp->result;
}

template <typename ReqType, typename RespType>
zx_status_t DoNoFailCall(const zx::channel& channel,
                         const ReqType&     req,
                         RespType*          resp,
                         zx::handle*        resp_handle_out = nullptr) {
    return DoCallImpl(channel, req, resp, resp_handle_out);
}

AudioDeviceStream::AudioDeviceStream(bool input, uint32_t dev_id)
    : input_(input) {
    snprintf(name_, sizeof(name_), "/dev/class/audio-%s/%03u",
             input_ ? "input" : "output",
             dev_id);
}

AudioDeviceStream::AudioDeviceStream(bool input, const char* dev_path)
    : input_(input) {
    strncpy(name_, dev_path, sizeof(name_));
    name_[sizeof(name_) - 1] = 0;
}

zx_status_t AudioDeviceStream::Open() {
    if (stream_ch_ != ZX_HANDLE_INVALID)
        return ZX_ERR_BAD_STATE;

    int fd = ::open(name(), O_RDONLY);
    if (fd < 0) {
        printf("Failed to open \"%s\" (res %d)\n", name(), fd);
        return fd;
    }

    ssize_t res = ::fdio_ioctl(fd, AUDIO_IOCTL_GET_CHANNEL,
                               nullptr, 0,
                               &stream_ch_, sizeof(stream_ch_));
    ::close(fd);

    if (res != sizeof(stream_ch_)) {
        printf("Failed to obtain channel (res %zd)\n", res);
        return static_cast<zx_status_t>(res);
    }

    return ZX_OK;
}

zx_status_t AudioDeviceStream::GetSupportedFormats(
        fbl::Vector<audio_stream_format_range_t>* out_formats) const {
    constexpr uint32_t MIN_RESP_SIZE = offsetof(audio_stream_cmd_get_formats_resp_t, format_ranges);
    audio_stream_cmd_get_formats_req req;
    audio_stream_cmd_get_formats_resp resp;
    uint32_t rxed;
    zx_status_t res;

    if (out_formats == nullptr) {
        return ZX_ERR_INVALID_ARGS;
    }

    req.hdr.cmd = AUDIO_STREAM_CMD_GET_FORMATS;
    req.hdr.transaction_id = 1;
    res = DoCallImpl(stream_ch_, req, &resp, nullptr, &rxed);
    if ((res != ZX_OK) || (rxed < MIN_RESP_SIZE)) {
        printf("Failed to fetch initial suppored format list chunk (res %d, rxed %u)\n",
                res, rxed);
        return res;
    }

    uint32_t expected_formats = resp.format_range_count;
    if (!expected_formats)
        return ZX_OK;

    out_formats->reset();
    fbl::AllocChecker ac;
    out_formats->reserve(expected_formats, &ac);
    if (!ac.check()) {
        printf("Failed to allocated %u entries for format ranges\n", expected_formats);
        return ZX_ERR_NO_MEMORY;
    }

    zx_txid_t txid = resp.hdr.transaction_id;
    uint32_t processed_formats = 0;
    while (true) {
        if (resp.hdr.cmd != AUDIO_STREAM_CMD_GET_FORMATS) {
            printf("Unexpected response command while fetching formats "
                   "(expected 0x%08x, got 0x%08x)\n",
                    AUDIO_STREAM_CMD_GET_FORMATS, resp.hdr.cmd);
            return ZX_ERR_INTERNAL;
        }

        if (resp.hdr.transaction_id != txid) {
            printf("Unexpected response transaction id while fetching formats "
                   "(expected 0x%08x, got 0x%08x)\n",
                    txid, resp.hdr.transaction_id);
            return ZX_ERR_INTERNAL;
        }

        if (resp.first_format_range_ndx != processed_formats) {
            printf("Bad format index while fetching formats (expected %u, got %hu)\n",
                    processed_formats, resp.first_format_range_ndx);
            return ZX_ERR_INTERNAL;
        }

        uint32_t todo = fbl::min(static_cast<uint32_t>(expected_formats - processed_formats),
                                  AUDIO_STREAM_CMD_GET_FORMATS_MAX_RANGES_PER_RESPONSE);
        size_t min_size = MIN_RESP_SIZE + (todo * sizeof(audio_stream_format_range_t));
        if (rxed < min_size) {
            printf("Short response while fetching formats (%u < %zu)\n", rxed, min_size);
            return ZX_ERR_INTERNAL;
        }

        for (uint16_t i = 0; i < todo; ++i) {
            out_formats->push_back(resp.format_ranges[i]);
        }

        processed_formats += todo;
        if (processed_formats == expected_formats)
            break;

        zx_signals_t pending_sig;
        res = stream_ch_.wait_one(ZX_CHANNEL_READABLE | ZX_CHANNEL_PEER_CLOSED,
                                  zx_deadline_after(CALL_TIMEOUT),
                                  &pending_sig);
        if (res != ZX_OK) {
            printf("Failed to wait for next response after processing %u/%u formats (res %d)\n",
                    processed_formats, expected_formats, res);
            return res;
        }

        res = stream_ch_.read(0u, &resp, sizeof(resp), &rxed, nullptr, 0, nullptr);
        if (res != ZX_OK) {
            printf("Failed to read next response after processing %u/%u formats (res %d)\n",
                    processed_formats, expected_formats, res);
            return res;
        }
    }

    return ZX_OK;
}

zx_status_t AudioDeviceStream::GetPlugState(audio_stream_cmd_plug_detect_resp_t* out_state,
                                            bool enable_notify) const {
    ZX_DEBUG_ASSERT(out_state != nullptr);
    audio_stream_cmd_plug_detect_req req;

    req.hdr.cmd = AUDIO_STREAM_CMD_PLUG_DETECT;
    req.hdr.transaction_id = 1;
    req.flags = enable_notify ? AUDIO_PDF_ENABLE_NOTIFICATIONS : AUDIO_PDF_NONE;

    zx_status_t res = DoNoFailCall(stream_ch_, req, out_state);
    if (res != ZX_OK)
        printf("Failed to fetch plug detect information! (res %d)\n", res);

    return res;
}

void AudioDeviceStream::DisablePlugNotifications() {
    audio_stream_cmd_plug_detect_req req;

    req.hdr.cmd = static_cast<audio_cmd_t>(AUDIO_STREAM_CMD_PLUG_DETECT | AUDIO_FLAG_NO_ACK);
    req.hdr.transaction_id = 1;
    req.flags = AUDIO_PDF_DISABLE_NOTIFICATIONS;

    stream_ch_.write(0, &req, sizeof(req), nullptr, 0);
}

zx_status_t AudioDeviceStream::SetMute(bool mute) {
    audio_stream_cmd_set_gain_req  req;
    audio_stream_cmd_set_gain_resp resp;

    req.hdr.cmd = AUDIO_STREAM_CMD_SET_GAIN;
    req.hdr.transaction_id = 1;
    req.flags = mute
              ? static_cast<audio_set_gain_flags_t>(AUDIO_SGF_MUTE_VALID | AUDIO_SGF_MUTE)
              : AUDIO_SGF_MUTE_VALID;

    zx_status_t res = DoCall(stream_ch_, req, &resp);
    if (res != ZX_OK)
        printf("Failed to %smute stream! (res %d)\n", mute ? "" : "un", res);
    else
        printf("Stream is now %smuted\n", mute ? "" : "un");

    return res;
}

zx_status_t AudioDeviceStream::SetGain(float gain) {
    audio_stream_cmd_set_gain_req  req;
    audio_stream_cmd_set_gain_resp resp;

    req.hdr.cmd = AUDIO_STREAM_CMD_SET_GAIN;
    req.hdr.transaction_id = 1;
    req.flags = AUDIO_SGF_GAIN_VALID;
    req.gain  = gain;

    zx_status_t res = DoCall(stream_ch_, req, &resp);
    if (res != ZX_OK) {
        printf("Failed to set gain to %.2f dB! (res %d)\n", gain, res);
    } else {
        printf("Gain is now %.2f dB.  Stream is %smuted.\n",
                resp.cur_gain, resp.cur_mute ? "" : "un");
    }

    return res;
}

zx_status_t AudioDeviceStream::GetGain(audio_stream_cmd_get_gain_resp_t* out_gain) const {
    if (out_gain == nullptr)
        return ZX_ERR_INVALID_ARGS;

    audio_stream_cmd_get_gain_req req;
    req.hdr.cmd = AUDIO_STREAM_CMD_GET_GAIN;
    req.hdr.transaction_id = 1;

    return DoNoFailCall(stream_ch_, req, out_gain);
}

zx_status_t AudioDeviceStream::PlugMonitor(float duration) {
    zx_time_t deadline = zx_deadline_after(ZX_SEC(static_cast<double>(duration)));
    audio_stream_cmd_plug_detect_resp resp;
    zx_status_t res = GetPlugState(&resp, true);
    if (res != ZX_OK)
        return res;

    zx_time_t last_plug_time = resp.plug_state_time;
    bool last_plug_state = (resp.flags & AUDIO_PDNF_PLUGGED);
    printf("Initial plug state is : %s.\n", last_plug_state ? "plugged" : "unplugged");

    if (resp.flags & AUDIO_PDNF_HARDWIRED) {
        printf("Stream reports that it is hardwired, Monitoring is not possible.\n");
        return ZX_OK;

    }

    auto ReportPlugState = [&last_plug_time, &last_plug_state](bool plug_state,
                                                               zx_time_t plug_time) {
        printf("Plug State now : %s (%.3lf sec since last change).\n",
               plug_state ? "plugged" : "unplugged",
               static_cast<double>(plug_time - last_plug_time) / ZX_SEC(1));

        last_plug_state = plug_state;
        last_plug_time  = plug_time;
    };

    if (resp.flags & AUDIO_PDNF_CAN_NOTIFY) {
        printf("Stream is capable of async notification.  Monitoring for %.2f seconds\n",
                duration);

        auto cleanup = fbl::MakeAutoCall([this]() { DisablePlugNotifications(); });
        while (true) {
            zx_signals_t pending;
            res = stream_ch_.wait_one(ZX_CHANNEL_PEER_CLOSED | ZX_CHANNEL_READABLE,
                                      deadline, &pending);

            if ((res != ZX_OK) || (pending & ZX_CHANNEL_PEER_CLOSED)) {
                if (res != ZX_ERR_TIMED_OUT)
                    printf("Error while waiting for plug notification (res %d)\n", res);

                if (pending & ZX_CHANNEL_PEER_CLOSED)
                    printf("Peer closed while waiting for plug notification\n");

                break;
            }

            ZX_DEBUG_ASSERT(pending & ZX_CHANNEL_READABLE);

            audio_stream_plug_detect_notify_t state;
            uint32_t bytes_read;
            res = stream_ch_.read(0, &state, sizeof(state), &bytes_read, nullptr, 0, nullptr);
            if (res != ZX_OK) {
                printf("Read failure while waiting for plug notification (res %d)\n", res);
                break;
            }

            if ((bytes_read != sizeof(state)) ||
                (state.hdr.cmd != AUDIO_STREAM_PLUG_DETECT_NOTIFY)) {
                printf("Size/type mismatch while waiting for plug notification.  "
                       "Got (%u/%u) Expected (%zu/%u)\n",
                       bytes_read, state.hdr.cmd,
                       sizeof(state), AUDIO_STREAM_PLUG_DETECT_NOTIFY);
                break;
            }

            bool plug_state = (state.flags & AUDIO_PDNF_PLUGGED);
            ReportPlugState(plug_state, state.plug_state_time);
        }
    } else {
        printf("Stream is not capable of async notification.  Polling for %.2f seconds\n",
                duration);

        while (true) {
            zx_time_t now = zx_time_get(ZX_CLOCK_MONOTONIC);
            if (now >= deadline)
                break;

            zx_time_t next_wake = fbl::min(deadline, now + ZX_MSEC(100u));

            zx_signals_t sigs;
            zx_status_t res = stream_ch_.wait_one(ZX_CHANNEL_PEER_CLOSED, next_wake, &sigs);

            if ((res != ZX_OK) && (res != ZX_ERR_TIMED_OUT)) {
                printf("Error waiting on stream channel (res %d)\n", res);
                break;
            }

            if (sigs & ZX_CHANNEL_PEER_CLOSED) {
                printf("Peer closed connection while polling plug state\n");
                break;
            }

            res = GetPlugState(&resp, true);
            if (res != ZX_OK) {
                printf("Failed to poll plug state (res %d)\n", res);
                break;
            }

            bool plug_state = (resp.flags & AUDIO_PDNF_PLUGGED);
            if (plug_state != last_plug_state)
                ReportPlugState(resp.flags, resp.plug_state_time);
        }
    }

    printf("Monitoring finished.\n");

    return ZX_OK;
}

zx_status_t AudioDeviceStream::SetFormat(uint32_t frames_per_second,
                                         uint16_t channels,
                                         audio_sample_format_t sample_format) {
    if ((stream_ch_ == ZX_HANDLE_INVALID) || (rb_ch_ != ZX_HANDLE_INVALID))
        return ZX_ERR_BAD_STATE;

    auto noflag_format = static_cast<audio_sample_format_t>(
            (sample_format & ~AUDIO_SAMPLE_FORMAT_FLAG_MASK));

    switch (noflag_format) {
    case AUDIO_SAMPLE_FORMAT_8BIT:         sample_size_ = 1; break;
    case AUDIO_SAMPLE_FORMAT_16BIT:        sample_size_ = 2; break;
    case AUDIO_SAMPLE_FORMAT_24BIT_PACKED: sample_size_ = 3; break;
    case AUDIO_SAMPLE_FORMAT_20BIT_IN32:
    case AUDIO_SAMPLE_FORMAT_24BIT_IN32:
    case AUDIO_SAMPLE_FORMAT_32BIT:
    case AUDIO_SAMPLE_FORMAT_32BIT_FLOAT:  sample_size_ = 4; break;
    default: return ZX_ERR_NOT_SUPPORTED;
    }

    channel_cnt_   = channels;
    frame_sz_      = channels * sample_size_;
    frame_rate_    = frames_per_second;
    sample_format_ = sample_format;

    audio_stream_cmd_set_format_req_t  req;
    audio_stream_cmd_set_format_resp_t resp;
    req.hdr.cmd            = AUDIO_STREAM_CMD_SET_FORMAT;
    req.hdr.transaction_id = 1;
    req.frames_per_second  = frames_per_second;
    req.channels           = channels;
    req.sample_format      = sample_format;

    zx::handle tmp;
    zx_status_t res = DoCall(stream_ch_, req, &resp, &tmp);
    if (res != ZX_OK) {
        printf("Failed to set format %uHz %hu-Ch fmt 0x%x (res %d)\n",
                frames_per_second, channels, sample_format, res);
    }

    // TODO(johngro) : Verify the type of this handle before transferring it to
    // our ring buffer channel handle.
    rb_ch_.reset(tmp.release());

    return res;
}

zx_status_t AudioDeviceStream::GetBuffer(uint32_t frames, uint32_t irqs_per_ring) {
    zx_status_t res;

    if(!frames)
        return ZX_ERR_INVALID_ARGS;

    if (!rb_ch_.is_valid() || rb_vmo_.is_valid() || !frame_sz_)
        return ZX_ERR_BAD_STATE;

    // Stash the FIFO depth, in case users need to know it.
    {
        audio_rb_cmd_get_fifo_depth_req_t  req;
        audio_rb_cmd_get_fifo_depth_resp_t resp;

        req.hdr.cmd = AUDIO_RB_CMD_GET_FIFO_DEPTH;
        req.hdr.transaction_id = 1;
        res = DoCall(rb_ch_, req, &resp);
        if (res != ZX_OK) {
            printf("Failed to fetch fifo depth (res %d)\n", res);
            return res;
        }

        fifo_depth_ = resp.fifo_depth;
    }

    {
        // Get a VMO representing the ring buffer we will share with the audio driver.
        audio_rb_cmd_get_buffer_req_t  req;
        audio_rb_cmd_get_buffer_resp_t resp;

        req.hdr.cmd                = AUDIO_RB_CMD_GET_BUFFER;
        req.hdr.transaction_id     = 1;
        req.min_ring_buffer_frames = frames;
        req.notifications_per_ring = irqs_per_ring;

        zx::handle tmp;
        res = DoCall(rb_ch_, req, &resp, &tmp);

        if ((res == ZX_OK) && (resp.result != ZX_OK))
            res = resp.result;

        if (res != ZX_OK) {
            printf("Failed to get driver ring buffer VMO (res %d)\n", res);
            return res;
        }

        // TODO(johngro) : Verify the type of this handle before transferring it to our VMO handle.
        rb_vmo_.reset(tmp.release());
    }

    // We have the buffer, fetch the size the driver finally decided on.
    uint64_t rb_sz;
    res = rb_vmo_.get_size(&rb_sz);
    if (res != ZX_OK) {
        printf("Failed to fetch ring buffer VMO size (res %d)\n", res);
        return res;
    }

    // Sanity check the size and stash it if it checks out.
    if ((rb_sz > fbl::numeric_limits<decltype(rb_sz_)>::max()) || ((rb_sz % frame_sz_) != 0)) {
        printf("Bad VMO size returned by audio driver! (size = %" PRIu64 " frame_sz = %u)\n",
                rb_sz, frame_sz_);
        return ZX_ERR_INVALID_ARGS;
    }

    rb_sz_ = static_cast<decltype(rb_sz_)>(rb_sz);

    // Map the VMO into our address space
    // TODO(johngro) : How do I specify the cache policy for this mapping?
    uint32_t flags = input_
                   ? ZX_VM_FLAG_PERM_READ
                   : ZX_VM_FLAG_PERM_READ | ZX_VM_FLAG_PERM_WRITE;
    res = zx_vmar_map(zx_vmar_root_self(), 0u,
                      rb_vmo_.get(), 0u, rb_sz_,
                      flags, reinterpret_cast<uintptr_t*>(&rb_virt_));
    if (res != ZX_OK) {
        printf("Failed to map ring buffer VMO (res %d)\n", res);
        return res;
    }

    // Success!  If this is an output device, zero out the buffer and we are done.
    if (!input_) {
        memset(rb_virt_, 0, rb_sz_);
    }

    return ZX_OK;
}

zx_status_t AudioDeviceStream::StartRingBuffer() {
    if (rb_ch_ == ZX_HANDLE_INVALID)
        return ZX_ERR_BAD_STATE;

    audio_rb_cmd_start_req_t  req;
    audio_rb_cmd_start_resp_t resp;

    req.hdr.cmd = AUDIO_RB_CMD_START;
    req.hdr.transaction_id = 1;

    zx_status_t res = DoCall(rb_ch_, req, &resp);

    if (res == ZX_OK) {
        start_ticks_ = resp.start_ticks;
    }

    return res;
}

zx_status_t AudioDeviceStream::StopRingBuffer() {
    if (rb_ch_ == ZX_HANDLE_INVALID)
        return ZX_ERR_BAD_STATE;

    start_ticks_ = 0;

    audio_rb_cmd_stop_req_t  req;
    audio_rb_cmd_stop_resp_t resp;

    req.hdr.cmd = AUDIO_RB_CMD_STOP;
    req.hdr.transaction_id = 1;

    return DoCall(rb_ch_, req, &resp);
}

void AudioDeviceStream::ResetRingBuffer() {
    rb_ch_.reset();
    rb_vmo_.reset();
    rb_sz_ = 0;
    rb_virt_ = nullptr;
}


bool AudioDeviceStream::IsChannelConnected(const zx::channel& ch) {
    if (!ch.is_valid())
        return false;

    zx_signals_t junk;
    return ch.wait_one(ZX_CHANNEL_PEER_CLOSED, 0u, &junk) != ZX_ERR_TIMED_OUT;
}


}  // namespace utils
}  // namespace audio
