/*
 * Copyright 2017 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 <android-base/thread_annotations.h>
#include <layerproto/LayerProtoHeader.h>
#include <utils/Errors.h>
#include <utils/StrongPointer.h>

#include <condition_variable>
#include <memory>
#include <mutex>
#include <queue>
#include <thread>

using namespace android::surfaceflinger;

namespace android {

class SurfaceFlinger;
constexpr auto operator""_MB(unsigned long long const num) {
    return num * 1024 * 1024;
}
/*
 * SurfaceTracing records layer states during surface flinging. Manages tracing state and
 * configuration.
 */
class SurfaceTracing {
public:
    SurfaceTracing(SurfaceFlinger& flinger);
    bool enable();
    bool disable();
    status_t writeToFile();
    bool isEnabled() const;
    /*
     * Adds a trace entry, must be called from the drawing thread or while holding the
     * SurfaceFlinger tracing lock.
     */
    void notify(const char* where);
    /*
     * Adds a trace entry, called while holding the SurfaceFlinger tracing lock.
     */
    void notifyLocked(const char* where) /* REQUIRES(mSfLock) */;

    void setBufferSize(size_t bufferSizeInBytes) { mConfig.bufferSize = bufferSizeInBytes; }
    void dump(std::string& result) const;

    enum : uint32_t {
        TRACE_CRITICAL = 1 << 0,
        TRACE_INPUT = 1 << 1,
        TRACE_COMPOSITION = 1 << 2,
        TRACE_EXTRA = 1 << 3,
        TRACE_HWC = 1 << 4,
        // Add non-geometry composition changes to the trace.
        TRACE_BUFFERS = 1 << 5,
        // Add entries from the drawing thread post composition.
        TRACE_SYNC = 1 << 6,
        TRACE_ALL = TRACE_CRITICAL | TRACE_INPUT | TRACE_COMPOSITION | TRACE_EXTRA,
    };
    void setTraceFlags(uint32_t flags) { mConfig.flags = flags; }
    bool flagIsSet(uint32_t flags) { return (mConfig.flags & flags) == flags; }

private:
    class Runner;
    static constexpr auto DEFAULT_BUFFER_SIZE = 5_MB;
    static constexpr auto DEFAULT_FILE_NAME = "/data/misc/wmtrace/layers_trace.pb";

    SurfaceFlinger& mFlinger;
    mutable std::mutex mTraceLock;
    bool mEnabled GUARDED_BY(mTraceLock) = false;
    std::unique_ptr<Runner> runner GUARDED_BY(mTraceLock);

    struct Config {
        uint32_t flags = TRACE_CRITICAL | TRACE_INPUT | TRACE_SYNC;
        size_t bufferSize = DEFAULT_BUFFER_SIZE;
    } mConfig;

    /*
     * ring buffer.
     */
    class LayersTraceBuffer {
    public:
        size_t size() const { return mSizeInBytes; }
        size_t used() const { return mUsedInBytes; }
        size_t frameCount() const { return mStorage.size(); }

        void setSize(size_t newSize) { mSizeInBytes = newSize; }
        void reset(size_t newSize);
        void emplace(LayersTraceProto&& proto);
        void flush(LayersTraceFileProto* fileProto);

    private:
        size_t mUsedInBytes = 0U;
        size_t mSizeInBytes = DEFAULT_BUFFER_SIZE;
        std::queue<LayersTraceProto> mStorage;
    };

    /*
     * Implements a synchronous way of adding trace entries. This must be called
     * from the drawing thread.
     */
    class Runner {
    public:
        Runner(SurfaceFlinger& flinger, SurfaceTracing::Config& config);
        virtual ~Runner() = default;
        virtual status_t stop();
        virtual status_t writeToFile();
        virtual void notify(const char* where);
        /* Cannot be called with a synchronous runner. */
        virtual void notifyLocked(const char* /* where */) {}
        void dump(std::string& result) const;

    protected:
        bool flagIsSet(uint32_t flags) { return (mConfig.flags & flags) == flags; }
        SurfaceFlinger& mFlinger;
        SurfaceTracing::Config mConfig;
        SurfaceTracing::LayersTraceBuffer mBuffer;
        uint32_t mMissedTraceEntries = 0;
        LayersTraceProto traceLayers(const char* where);
    };

    /*
     * Implements asynchronous way to add trace entries called from a separate thread while holding
     * the SurfaceFlinger tracing lock. Trace entries may be missed if the tracing thread is not
     * scheduled in time.
     */
    class AsyncRunner : public Runner {
    public:
        AsyncRunner(SurfaceFlinger& flinger, SurfaceTracing::Config& config, std::mutex& sfLock);
        virtual ~AsyncRunner() = default;
        status_t stop() override;
        status_t writeToFile() override;
        void notify(const char* where) override;
        void notifyLocked(const char* where);

    private:
        std::mutex& mSfLock;
        std::condition_variable mCanStartTrace;
        std::thread mThread;
        const char* mWhere = "";
        bool mWriteToFile = false;
        bool mEnabled = false;
        bool mAddEntry = false;
        void loop();
        bool traceWhenNotified(LayersTraceProto* outProto);
    };
};

} // namespace android
