// Copyright (C) 2016 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.
#pragma once

#include "OpenglRender/RenderChannel.h"
#include "RendererImpl.h"

#include "android/base/Compiler.h"
#include "android/base/synchronization/Lock.h"
#include "android/base/synchronization/MessageChannel.h"

#include <atomic>
#include <memory>

namespace emugl {

class RenderChannelImpl final : public RenderChannel {
public:
    RenderChannelImpl(std::shared_ptr<RendererImpl> renderer);

public:
    // RenderChannel implementation, operations provided for a guest system
    virtual void setEventCallback(EventCallback callback) override final;

    virtual bool write(ChannelBuffer&& buffer) override final;
    virtual bool read(ChannelBuffer* buffer, CallType type) override final;

    virtual State currentState() const override final {
        return mState.load(std::memory_order_acquire);
    }

    virtual void stop() override final;
    virtual bool isStopped() const override final;

public:
    // These functions are for the RenderThread, they could be called in
    // parallel with the ones from the RenderChannel interface. Make sure the
    // internal state remains consistent all the time.
    void writeToGuest(ChannelBuffer&& buf);
    size_t readFromGuest(ChannelBuffer::value_type* buf, size_t size,
                         bool blocking);
    void forceStop();

private:
    DISALLOW_COPY_ASSIGN_AND_MOVE(RenderChannelImpl);

private:
    void onEvent(bool byGuest);
    State calcState() const;
    void stop(bool byGuest);

private:
    std::shared_ptr<RendererImpl> mRenderer;

    EventCallback mOnEvent;

    // Protects the state recalculation and writes to mState.
    //
    // The correctness condition governing the relationship between mFromGuest,
    // mToGuest, and mState is that we can't reach a potentially stable state
    // (i.e., at the end of a set of invocations of publically-visible
    // operations) in which either:
    //  - mFromGuest().size() < mFromGuest.capacity(), yet state does not have
    //    State::CanWrite, or
    //  - mToGuest().size > 0, yet state does not have State::CanRead.
    // Clients assume they can poll currentState() and have the indicate whether
    // a write or read might possibly succeed, and this correctness condition
    // makes that assumption valid -- if a write or read might succeed,
    // mState is required to eventually indicate this.
    android::base::Lock mStateLock;
    std::atomic<State> mState;

    bool mStopped = false;

    android::base::MessageChannel<ChannelBuffer, 1024> mFromGuest;
    android::base::MessageChannel<ChannelBuffer, 16> mToGuest;

    ChannelBuffer mFromGuestBuffer;
    size_t mFromGuestBufferLeft = 0;
};

}  // namespace emugl
