// Copyright 2017 The Dawn Authors
//
// 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.

#ifndef SRC_DAWN_NATIVE_PERSTAGE_H_
#define SRC_DAWN_NATIVE_PERSTAGE_H_

#include "dawn/common/Assert.h"
#include "dawn/common/BitSetIterator.h"
#include "dawn/common/Constants.h"
#include "dawn/native/Error.h"

#include "dawn/native/dawn_platform.h"

#include <array>

namespace dawn::native {

    enum class SingleShaderStage { Vertex, Fragment, Compute };

    static_assert(static_cast<uint32_t>(SingleShaderStage::Vertex) < kNumStages);
    static_assert(static_cast<uint32_t>(SingleShaderStage::Fragment) < kNumStages);
    static_assert(static_cast<uint32_t>(SingleShaderStage::Compute) < kNumStages);

    static_assert(static_cast<uint32_t>(wgpu::ShaderStage::Vertex) ==
                  (1 << static_cast<uint32_t>(SingleShaderStage::Vertex)));
    static_assert(static_cast<uint32_t>(wgpu::ShaderStage::Fragment) ==
                  (1 << static_cast<uint32_t>(SingleShaderStage::Fragment)));
    static_assert(static_cast<uint32_t>(wgpu::ShaderStage::Compute) ==
                  (1 << static_cast<uint32_t>(SingleShaderStage::Compute)));

    BitSetIterator<kNumStages, SingleShaderStage> IterateStages(wgpu::ShaderStage stages);
    wgpu::ShaderStage StageBit(SingleShaderStage stage);

    static constexpr wgpu::ShaderStage kAllStages =
        static_cast<wgpu::ShaderStage>((1 << kNumStages) - 1);

    template <typename T>
    class PerStage {
      public:
        PerStage() = default;
        explicit PerStage(const T& initialValue) {
            mData.fill(initialValue);
        }

        T& operator[](SingleShaderStage stage) {
            DAWN_ASSERT(static_cast<uint32_t>(stage) < kNumStages);
            return mData[static_cast<uint32_t>(stage)];
        }
        const T& operator[](SingleShaderStage stage) const {
            DAWN_ASSERT(static_cast<uint32_t>(stage) < kNumStages);
            return mData[static_cast<uint32_t>(stage)];
        }

        T& operator[](wgpu::ShaderStage stageBit) {
            uint32_t bit = static_cast<uint32_t>(stageBit);
            DAWN_ASSERT(bit != 0 && IsPowerOfTwo(bit) && bit <= (1 << kNumStages));
            return mData[Log2(bit)];
        }
        const T& operator[](wgpu::ShaderStage stageBit) const {
            uint32_t bit = static_cast<uint32_t>(stageBit);
            DAWN_ASSERT(bit != 0 && IsPowerOfTwo(bit) && bit <= (1 << kNumStages));
            return mData[Log2(bit)];
        }

      private:
        std::array<T, kNumStages> mData;
    };

}  // namespace dawn::native

#endif  // SRC_DAWN_NATIVE_PERSTAGE_H_
