/* Copyright (c) 2019-2020 The Khronos Group Inc.
 * Copyright (c) 2019-2020 Valve Corporation
 * Copyright (c) 2019-2020 LunarG, Inc.
 * Copyright (C) 2019-2020 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...
struct 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 Layouts {
        VkImageLayout current_layout;
        VkImageLayout initial_layout;
    };

    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 SubresourceRangeLayout {
        VkImageSubresourceRange subresource_range;
        VkImageLayout current_layout;
        VkImageLayout initial_layout;
        bool operator==(const SubresourceRangeLayout& rhs) const {
            bool is_equal = (current_layout == rhs.current_layout) && (initial_layout == rhs.initial_layout) &&
                            (subresource_range == rhs.subresource_range);
            return is_equal;
        }
        bool operator!=(const SubresourceRangeLayout& rhs) const { return !(*this == rhs); }
    };

    using RangeMap = subresource_adapter::BothRangeMap<VkImageLayout, 16>;
    template <typename MapA, typename MapB>
    using ParallelIterator = sparse_container::parallel_iterator<MapA, MapB>;
    using LayoutMap = RangeMap;
    using InitialLayoutMap = RangeMap;
    using InitialLayoutStates = std::vector<std::unique_ptr<InitialLayoutState>>;

    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_(), parallel_it_(), 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& current, const RangeMap& initial, const Encoder& encoder,
                      const VkImageSubresourceRange& subres, bool skip_invalid, bool always_get_initial);
        void UpdateRangeAndValue();
        void ForceEndCondition() { pos_.subresource.aspectMask = 0; }

        RangeGenerator range_gen_;
        ParallelIterator<const RangeMap, const RangeMap> parallel_it_;
        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_.current, layouts_.initial, 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.
    inline size_t InitialLayoutSize() const { return layouts_.initial.size(); }
    inline size_t CurrentLayoutSize() const { return layouts_.current.size(); }

    bool SetSubresourceRangeLayout(const CMD_BUFFER_STATE& cb_state, const VkImageSubresourceRange& range, VkImageLayout layout,
                                   VkImageLayout expected_layout = kInvalidLayout);
    bool SetSubresourceRangeInitialLayout(const CMD_BUFFER_STATE& cb_state, const VkImageSubresourceRange& range,
                                          VkImageLayout layout, const IMAGE_VIEW_STATE* view_state = nullptr);
    bool SetSubresourceRangeInitialLayout(const CMD_BUFFER_STATE& cb_state, VkImageLayout layout,
                                          const IMAGE_VIEW_STATE& view_state);
    bool ForRange(const VkImageSubresourceRange& range, const Callback& callback, bool skip_invalid = true,
                  bool always_get_initial = false) const;
    VkImageLayout GetSubresourceLayout(const VkImageSubresource& subresource) const;
    VkImageLayout GetSubresourceInitialLayout(const VkImageSubresource& subresource) const;
    Layouts GetSubresourceLayouts(const VkImageSubresource& subresource, bool always_get_initial = true) 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 InitialLayoutMap& GetInitialLayoutMap() const { return layouts_.initial; }
    const LayoutMap& GetCurrentLayoutMap() const { return layouts_.current; }
    ImageSubresourceLayoutMap(const IMAGE_STATE& image_state);
    ~ImageSubresourceLayoutMap() {}
    const IMAGE_STATE* GetImageView() const { return &image_state_; };

    struct LayoutMaps {
        LayoutMap current;
        InitialLayoutMap initial;
        LayoutMaps(typename LayoutMap::index_type size) : current(size), initial(size) {}
    };

  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); }

    inline InitialLayoutState* UpdateInitialLayoutState(const IndexRange& range, InitialLayoutState* initial_state,
                                                        const CMD_BUFFER_STATE& cb_state, const IMAGE_VIEW_STATE* view_state) {
        if (!initial_state) {
            // Allocate on demand...  initial_layout_states_ holds ownership as a unique_ptr, while
            // each subresource has a non-owning copy of the plain pointer.
            initial_state = new InitialLayoutState(cb_state, view_state);
            initial_layout_states_.emplace_back(initial_state);
        }
        assert(initial_state);
        sparse_container::update_range_value(initial_layout_state_map_, range, initial_state, WritePolicy::prefer_dest);
        return initial_state;
    }

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

  private:
    const IMAGE_STATE& image_state_;
    const Encoder& encoder_;
    LayoutMaps layouts_;
    InitialLayoutStates initial_layout_states_;
    InitialLayoutStateMap initial_layout_state_map_;

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