/*
 * Copyright (C) 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 "Properties.h"
#include "utils/Macros.h"

#include <utils/Timers.h>

#include <array>
#include <functional>
#include <tuple>

namespace android {
namespace uirenderer {

enum JankType {
    kMissedVsync = 0,
    kHighInputLatency,
    kSlowUI,
    kSlowSync,
    kSlowRT,
    kMissedDeadline,
    kMissedDeadlineLegacy,

    // must be last
    NUM_BUCKETS,
};

// For testing
class MockProfileData;

// Try to keep as small as possible, should match ASHMEM_SIZE in
// GraphicsStatsService.java
class ProfileData {
    PREVENT_COPY_AND_ASSIGN(ProfileData);

public:
    ProfileData() { reset(); }

    void reset();
    void mergeWith(const ProfileData& other);
    void dump(int fd) const;
    uint32_t findPercentile(int percentile) const;
    uint32_t findGPUPercentile(int percentile) const;

    void reportFrame(int64_t duration);
    void reportGPUFrame(int64_t duration);
    void reportJank() { mJankFrameCount++; }
    void reportJankLegacy() { mJankLegacyFrameCount++; }
    void reportJankType(JankType type) { mJankTypeCounts[static_cast<int>(type)]++; }

    uint32_t totalFrameCount() const { return mTotalFrameCount; }
    uint32_t jankFrameCount() const { return mJankFrameCount; }
    uint32_t jankLegacyFrameCount() const { return mJankLegacyFrameCount; }
    nsecs_t statsStartTime() const { return mStatStartTime; }
    uint32_t jankTypeCount(JankType type) const { return mJankTypeCounts[static_cast<int>(type)]; }
    RenderPipelineType pipelineType() const { return mPipelineType; }

    struct HistogramEntry {
        uint32_t renderTimeMs;
        uint32_t frameCount;
    };
    void histogramForEach(const std::function<void(HistogramEntry)>& callback) const;
    void histogramGPUForEach(const std::function<void(HistogramEntry)>& callback) const;

    constexpr static int HistogramSize() {
        return std::tuple_size<decltype(ProfileData::mFrameCounts)>::value +
               std::tuple_size<decltype(ProfileData::mSlowFrameCounts)>::value;
    }

    constexpr static int GPUHistogramSize() {
        return std::tuple_size<decltype(ProfileData::mGPUFrameCounts)>::value;
    }

    // Visible for testing
    static uint32_t frameTimeForFrameCountIndex(uint32_t index);
    static uint32_t frameTimeForSlowFrameCountIndex(uint32_t index);
    static uint32_t GPUFrameTimeForFrameCountIndex(uint32_t index);

private:
    // Open our guts up to unit tests
    friend class MockProfileData;

    std::array<uint32_t, NUM_BUCKETS> mJankTypeCounts;
    // See comments on kBucket* constants for what this holds
    std::array<uint32_t, 57> mFrameCounts;
    // Holds a histogram of frame times in 50ms increments from 150ms to 5s
    std::array<uint16_t, 97> mSlowFrameCounts;
    // Holds a histogram of GPU draw times in 1ms increments. Frames longer than 25ms are placed in
    // last bucket.
    std::array<uint32_t, 26> mGPUFrameCounts;

    uint32_t mTotalFrameCount;
    uint32_t mJankFrameCount;
    uint32_t mJankLegacyFrameCount;
    nsecs_t mStatStartTime;

    // true if HWUI renders with Vulkan pipeline
    RenderPipelineType mPipelineType;
};

// For testing
class MockProfileData : public ProfileData {
public:
    std::array<uint32_t, NUM_BUCKETS>& editJankTypeCounts() { return mJankTypeCounts; }
    std::array<uint32_t, 57>& editFrameCounts() { return mFrameCounts; }
    std::array<uint16_t, 97>& editSlowFrameCounts() { return mSlowFrameCounts; }
    uint32_t& editTotalFrameCount() { return mTotalFrameCount; }
    uint32_t& editJankFrameCount() { return mJankFrameCount; }
    nsecs_t& editStatStartTime() { return mStatStartTime; }
};

} /* namespace uirenderer */
} /* namespace android */
