// 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-input.h>
#include <audio-utils/audio-stream.h>
#include <fbl/algorithm.h>
#include <fbl/alloc_checker.h>
#include <limits>
#include <zircon/time.h>
#include <zircon/types.h>

namespace audio {
namespace utils {

static constexpr zx_duration_t CHUNK_TIME = ZX_MSEC(100);
static constexpr float MIN_DURATION = 0.100f;
static constexpr float MAX_DURATION = 86400.0f;

fbl::unique_ptr<AudioInput> AudioInput::Create(uint32_t dev_id) {
    fbl::AllocChecker ac;
    fbl::unique_ptr<AudioInput> res(new (&ac) AudioInput(dev_id));
    if (!ac.check())
        return nullptr;
    return res;
}

fbl::unique_ptr<AudioInput> AudioInput::Create(const char* dev_path) {
    fbl::AllocChecker ac;
    fbl::unique_ptr<AudioInput> res(new (&ac) AudioInput(dev_path));
    if (!ac.check())
        return nullptr;
    return res;
}

zx_status_t AudioInput::Record(AudioSink& sink, float duration_seconds) {
    AudioStream::Format fmt = {
        .frame_rate = frame_rate_,
        .channels = static_cast<uint16_t>(channel_cnt_),
        .sample_format = sample_format_,
    };

    duration_seconds = fbl::clamp(duration_seconds, MIN_DURATION, MAX_DURATION);

    zx_status_t res = sink.SetFormat(fmt);
    if (res != ZX_OK) {
        printf("Failed to set sink format (rate %u, chan_count %u, fmt 0x%08x, res %d)\n",
                frame_rate_, channel_cnt_, sample_format_, res);
        return res;
    }

    uint64_t ring_bytes_64 =
        (zx_duration_mul_int64(CHUNK_TIME, frame_rate_) / ZX_SEC(1)) * frame_sz_;
    if (ring_bytes_64 > std::numeric_limits<uint32_t>::max()) {
        printf("Invalid frame rate %u\n", frame_rate_);
        return res;
    }

    uint32_t ring_bytes  = static_cast<uint32_t>(ring_bytes_64);
    uint32_t ring_frames = ring_bytes / frame_sz_;

    res = GetBuffer(ring_frames, 2u);
    if (res != ZX_OK) {
        printf("Failed to establish ring buffer (%u frames, res %d)\n",
                ring_frames, res);
        return res;
    }

    zx_duration_t duration_nsec = static_cast<zx_time_t>(ZX_SEC(1)
                                  * static_cast<double>(duration_seconds));
    zx_time_t stop_time = zx_time_add_duration(zx_clock_get_monotonic(), duration_nsec);
    printf("Recording for %.1f seconds\n", duration_seconds);

    res = StartRingBuffer();
    if (res != ZX_OK) {
        printf("Failed to start capture (res %d)\n", res);
        return res;
    }

    uint32_t  rd_ptr = 0;
    bool      peer_connected = true;
    while (true) {
        zx_signals_t sigs;

        res = rb_ch_.wait_one(ZX_CHANNEL_READABLE | ZX_CHANNEL_PEER_CLOSED,
                              zx::time(stop_time), &sigs);

        // If we get a timeout error, we have hit our stop time.
        if (res == ZX_ERR_TIMED_OUT) break;

        if (res != ZX_OK) {
            printf("Failed to wait for notificiation (res %d)\n", res);
            break;
        }

        if (sigs & ZX_CHANNEL_PEER_CLOSED) {
            printf("Peer closed connection during record!\n");
            peer_connected = false;
            break;
        }

        audio_rb_position_notify_t pos_notif;

        uint32_t bytes_read, junk;
        res = rb_ch_.read(0,
                          &pos_notif, nullptr, sizeof(pos_notif), 0,
                          &bytes_read, &junk);
        if (res != ZX_OK) {
            printf("Failed to read notification from ring buffer channel (res %d)\n", res);
            break;
        }

        if (bytes_read != sizeof(pos_notif)) {
            printf("Bad size when reading notification from ring buffer channel (%u != %zu)\n",
                   bytes_read, sizeof(pos_notif));
            res = ZX_ERR_INTERNAL;
            break;
        }

        if (pos_notif.hdr.cmd != AUDIO_RB_POSITION_NOTIFY) {
            printf("Unexpected command type when reading notification from ring "
                   "buffer channel (cmd %04x)\n", pos_notif.hdr.cmd);
            res = ZX_ERR_INTERNAL;
            break;
        }

        uint32_t todo = pos_notif.ring_buffer_pos + rb_sz_ - rd_ptr;
        if (todo >= rb_sz_)
            todo -= rb_sz_;

        ZX_DEBUG_ASSERT(todo < rb_sz_);
        ZX_DEBUG_ASSERT(rd_ptr < rb_sz_);

        uint32_t space = rb_sz_ - rd_ptr;
        uint32_t amt = fbl::min(space, todo);
        auto data = static_cast<const uint8_t*>(rb_virt_) + rd_ptr;

        res = zx_cache_flush(data, amt, ZX_CACHE_FLUSH_DATA | ZX_CACHE_FLUSH_INVALIDATE);
        if (res != ZX_OK) {
            printf("Failed to cache invalidate(res %d).\n", res);
            break;
        }

        res = sink.PutFrames(data, amt);
        if (res != ZX_OK) {
            printf("Failed to record %u bytes (res %d)\n", amt, res);
            break;
        }

        if (amt < todo) {
            amt = todo - amt;
            ZX_DEBUG_ASSERT(amt < rb_sz_);

            res = zx_cache_flush(rb_virt_, amt, ZX_CACHE_FLUSH_DATA | ZX_CACHE_FLUSH_INVALIDATE);
            if (res != ZX_OK) {
                printf("Failed to cache invalidate(res %d) %d\n", res, __LINE__);
                break;
            }

            res = sink.PutFrames(rb_virt_, amt);
            if (res != ZX_OK) {
                printf("Failed to record %u bytes (res %d)\n", amt, res);
                break;
            }

            rd_ptr = amt;
        } else {
            rd_ptr += amt;
            if (rd_ptr >= rb_sz_) {
                ZX_DEBUG_ASSERT(rd_ptr == rb_sz_);
                rd_ptr = 0;
            }
        }
    }

    if (peer_connected) {
        StopRingBuffer();
    }

    zx_status_t finalize_res = sink.Finalize();
    return (res == ZX_OK) ? finalize_res : res;
}

}  // namespace utils
}  // namespace audio
