/* Copyright (c) 2019-2021 The Khronos Group Inc.
 * Copyright (c) 2019-2021 Valve Corporation
 * Copyright (c) 2019-2021 LunarG, Inc.
 * Copyright (C) 2019-2021 Google Inc.
 *
 * 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.
 *
 * John Zulauf <jzulauf@lunarg.com>
 *
 */
#pragma once
#ifndef IMAGE_LAYOUT_MAP_H_
#define IMAGE_LAYOUT_MAP_H_

#include <functional>
#include <memory>
#include <vector>

#include "range_vector.h"
#include "subresource_adapter.h"
#ifndef SPARSE_CONTAINER_UNIT_TEST
#include "vulkan/vulkan.h"
#include "vk_layer_logging.h"

// Forward declarations...
class CMD_BUFFER_STATE;
class IMAGE_STATE;
class IMAGE_VIEW_STATE;
#endif

namespace image_layout_map {
const static VkImageLayout kInvalidLayout = VK_IMAGE_LAYOUT_MAX_ENUM;

// Common types for this namespace
using IndexType = subresource_adapter::IndexType;
using IndexRange = sparse_container::range<IndexType>;
using Encoder = subresource_adapter::RangeEncoder;
using NoSplit = sparse_container::insert_range_no_split_bounds;
using RangeGenerator = subresource_adapter::RangeGenerator;
using SubresourceGenerator = subresource_adapter::SubresourceGenerator;
using WritePolicy = subresource_adapter::WritePolicy;

struct InitialLayoutState {
    VkImageView image_view;          // For relaxed matching rule evaluation, else VK_NULL_HANDLE
    VkImageAspectFlags aspect_mask;  // For relaxed matching rules... else 0
    LoggingLabel label;
    InitialLayoutState(const CMD_BUFFER_STATE& cb_state_, const IMAGE_VIEW_STATE* view_state_);
    InitialLayoutState() : image_view(VK_NULL_HANDLE), aspect_mask(0), label() {}
};

class ImageSubresourceLayoutMap {
  public:
    typedef std::function<bool(const VkImageSubresource&, VkImageLayout, VkImageLayout)> Callback;

    struct SubresourceLayout {
        VkImageSubresource subresource;
        VkImageLayout current_layout;
        VkImageLayout initial_layout;

        bool operator==(const SubresourceLayout& rhs) const;
        bool operator!=(const SubresourceLayout& rhs) const { return !(*this == rhs); }
        SubresourceLayout(const VkImageSubresource& subresource_, VkImageLayout current_layout_, VkImageLayout initial_layout_)
            : subresource(subresource_), current_layout(current_layout_), initial_layout(initial_layout_) {}
        SubresourceLayout() = default;
    };

    struct LayoutEntry {
        VkImageLayout initial_layout;
        VkImageLayout current_layout;
        InitialLayoutState* state;

        LayoutEntry(VkImageLayout initial_ = kInvalidLayout, VkImageLayout current_ = kInvalidLayout,
                    InitialLayoutState* s = nullptr)
            : initial_layout(initial_), current_layout(current_), state(s) {}

        bool operator!=(const LayoutEntry& rhs) const {
            return initial_layout != rhs.initial_layout || current_layout != rhs.current_layout || state != rhs.state;
        }
        bool CurrentWillChange(VkImageLayout new_layout) const {
            return new_layout != kInvalidLayout && current_layout != new_layout;
        }
        bool Update(const LayoutEntry& src) {
            bool updated_current = false;
            // current_layout can be updated repeatedly.
            if (CurrentWillChange(src.current_layout)) {
                current_layout = src.current_layout;
                updated_current = true;
            }
            // initial_layout and state cannot be updated once they have a valid value.
            if (initial_layout == kInvalidLayout) {
                initial_layout = src.initial_layout;
            }
            if (state == nullptr) {
                state = src.state;
            }
            return updated_current;
        }
        // updater for splice()
        struct Updater {
            bool update(LayoutEntry& dst, const LayoutEntry& src) const { return dst.Update(src); }
            layer_data::optional<LayoutEntry> insert(const LayoutEntry& src) const { return layer_data::optional<LayoutEntry>(layer_data::in_place, src); }
        };
    };
    using RangeMap = subresource_adapter::BothRangeMap<LayoutEntry, 16>;
    using LayoutMap = RangeMap;
    using InitialLayoutStates = small_vector<InitialLayoutState, 2, uint32_t>;

    class ConstIterator {
      public:
        ConstIterator& operator++() {
            Increment();
            return *this;
        }
        void IncrementInterval();
        const SubresourceLayout* operator->() const { return &pos_; }
        const SubresourceLayout& operator*() const { return pos_; }

        ConstIterator() : range_gen_(), layouts_(nullptr), iter_(), skip_invalid_(false), always_get_initial_(false), pos_() {}
        bool AtEnd() const { return pos_.subresource.aspectMask == 0; }

        // Only for comparisons to end()
        // Note: if a fully function == is needed, the AtEnd needs to be maintained, as end_iterator is a static.
        bool operator==(const ConstIterator& other) const { return AtEnd() && other.AtEnd(); };
        bool operator!=(const ConstIterator& other) const { return AtEnd() != other.AtEnd(); };

      protected:
        void Increment();
        friend ImageSubresourceLayoutMap;
        ConstIterator(const RangeMap& layouts, const Encoder& encoder, const VkImageSubresourceRange& subres, bool skip_invalid,
                      bool always_get_initial);
        void UpdateRangeAndValue();
        void ForceEndCondition() { pos_.subresource.aspectMask = 0; }

        RangeGenerator range_gen_;
        const RangeMap* layouts_;
        RangeMap::const_iterator iter_;
        bool skip_invalid_;
        bool always_get_initial_;
        SubresourceLayout pos_;
        IndexType current_index_ = 0;
        IndexType constant_value_bound_ = 0;
    };

    ConstIterator Find(const VkImageSubresourceRange& subres_range, bool skip_invalid = true,
                       bool always_get_initial = false) const {
        if (InRange(subres_range)) {
            return ConstIterator(layouts_, encoder_, subres_range, skip_invalid, always_get_initial);
        }
        return End();
    }

    // Begin is a find of the full range with the default skip/ always get parameters
    ConstIterator Begin(bool always_get_initial = true) const;
    inline ConstIterator begin() const { return Begin(); }  // STL style, for range based loops and familiarity
    const ConstIterator& End() const { return end_iterator; }
    const ConstIterator& end() const { return End(); }  // STL style, for range based loops and familiarity.

    bool SetSubresourceRangeLayout(const CMD_BUFFER_STATE& cb_state, const VkImageSubresourceRange& range, VkImageLayout layout,
                                   VkImageLayout expected_layout = kInvalidLayout);
    void SetSubresourceRangeInitialLayout(const CMD_BUFFER_STATE& cb_state, const VkImageSubresourceRange& range,
                                          VkImageLayout layout);
    void SetSubresourceRangeInitialLayout(const CMD_BUFFER_STATE& cb_state, VkImageLayout layout,
                                          const IMAGE_VIEW_STATE& view_state);
    const LayoutEntry* GetSubresourceLayouts(const VkImageSubresource& subresource) const;
    const InitialLayoutState* GetSubresourceInitialLayoutState(const IndexType index) const;
    const InitialLayoutState* GetSubresourceInitialLayoutState(const VkImageSubresource& subresource) const;
    bool UpdateFrom(const ImageSubresourceLayoutMap& from);
    uintptr_t CompatibilityKey() const;
    const LayoutMap& GetLayoutMap() const { return layouts_; }
    ImageSubresourceLayoutMap(const IMAGE_STATE& image_state);
    ~ImageSubresourceLayoutMap() {}
    const IMAGE_STATE* GetImageView() const { return &image_state_; };

  protected:
    // This looks a bit ponderous but kAspectCount is a compile time constant
    VkImageSubresource Decode(IndexType index) const {
        const auto subres = encoder_.Decode(index);
        return encoder_.MakeVkSubresource(subres);
    }

    inline uint32_t LevelLimit(uint32_t level) const { return std::min(encoder_.Limits().mipLevel, level); }
    inline uint32_t LayerLimit(uint32_t layer) const { return std::min(encoder_.Limits().arrayLayer, layer); }

    bool InRange(const VkImageSubresource& subres) const { return encoder_.InRange(subres); }
    bool InRange(const VkImageSubresourceRange& range) const { return encoder_.InRange(range); }

    // This map *also* needs "write once" semantics
    using InitialLayoutStateMap = subresource_adapter::BothRangeMap<InitialLayoutState*, 16>;

  private:
    const IMAGE_STATE& image_state_;
    const Encoder& encoder_;
    LayoutMap layouts_;
    InitialLayoutStates initial_layout_states_;

    static const ConstIterator end_iterator;  // Just to hold the end condition tombstone (aspectMask == 0)
};
}  // namespace image_layout_map
#endif
