/*
 * Copyright 2022 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 "FrontEnd/LayerCreationArgs.h"
#include "RequestedLayerState.h"
#include "ftl/small_vector.h"

namespace android::surfaceflinger::frontend {
class LayerHierarchyBuilder;

// LayerHierarchy allows us to navigate the layer hierarchy in z-order, or depth first traversal.
// The hierarchy is created from a set of RequestedLayerStates. The hierarchy itself does not
// contain additional states. Instead, it is a representation of RequestedLayerStates as a graph.
//
// Each node in the hierarchy can be visited by multiple parents (making this a graph). While
// traversing the hierarchy, a new concept called Variant can be used to understand the
// relationship of the layer to its parent. The following variants are possible:
// Attached - child of the parent
// Detached - child of the parent but currently relative parented to another layer
// Relative - relative child of the parent
// Mirror - mirrored from another layer
//
// By representing the hierarchy as a graph, we can represent mirrored layer hierarchies without
// cloning the layer requested state. The mirrored hierarchy and its corresponding
// RequestedLayerStates are kept in sync because the mirrored hierarchy does not clone any
// states.
class LayerHierarchy {
public:
    enum Variant : uint32_t {
        Attached, // child of the parent
        Detached, // child of the parent but currently relative parented to another layer
        Relative, // relative child of the parent
        Mirror,   // mirrored from another layer
        ftl_first = Attached,
        ftl_last = Mirror,
    };
    // Represents a unique path to a node.
    // The layer hierarchy is represented as a graph. Each node can be visited by multiple parents.
    // This allows us to represent mirroring in an efficient way. See the example below:
    // root
    // ├─ A {Traversal path id = 1}
    // ├─ B {Traversal path id = 2}
    // │  ├─ C {Traversal path id = 3}
    // │  ├─ D {Traversal path id = 4}
    // │  └─ E {Traversal path id = 5}
    // ├─ F (Mirrors B) {Traversal path id = 6}
    // └─ G (Mirrors F) {Traversal path id = 7}
    //
    // C, D and E can be traversed via B or via F then B or via G then F then B.
    // Depending on how the node is reached, its properties such as geometry or visibility might be
    // different. And we can uniquely identify the node by keeping track of the nodes leading up to
    // it. But to be more efficient we only need to track the nodes id and the top mirror root path.
    // So C for example, would have the following unique traversal paths:
    //  - {Traversal path id = 3}
    //  - {Traversal path id = 3, mirrorRootId = 6}
    //  - {Traversal path id = 3, mirrorRootId = 7}

    struct TraversalPath {
        uint32_t id;
        LayerHierarchy::Variant variant;
        // Mirrored layers can have a different geometry than their parents so we need to track
        // the mirror roots in the traversal.
        uint32_t mirrorRootId = UNASSIGNED_LAYER_ID;
        // Relative layers can be visited twice, once by their parent and then once again by
        // their relative parent. We keep track of the roots here to detect any loops in the
        // hierarchy. If a relative root already exists in the list while building the
        // TraversalPath, it means that somewhere in the hierarchy two layers are relatively
        // parented to each other.
        ftl::SmallVector<uint32_t, 5> relativeRootIds;
        // First duplicate relative root id found. If this is a valid layer id that means we are
        // in a loop.
        uint32_t invalidRelativeRootId = UNASSIGNED_LAYER_ID;
        // See isAttached()
        bool detached = false;
        bool hasRelZLoop() const { return invalidRelativeRootId != UNASSIGNED_LAYER_ID; }
        // Returns true if this node is reached via one or more relative parents.
        bool isRelative() const { return !relativeRootIds.empty(); }
        // Returns true if the node or its parents are not Detached.
        bool isAttached() const { return !detached; }
        // Returns true if the node is a clone.
        bool isClone() const { return mirrorRootId != UNASSIGNED_LAYER_ID; }
        TraversalPath getMirrorRoot() const;

        bool operator==(const TraversalPath& other) const {
            return id == other.id && mirrorRootId == other.mirrorRootId;
        }
        std::string toString() const;

        static const TraversalPath ROOT;
    };

    struct TraversalPathHash {
        std::size_t operator()(const LayerHierarchy::TraversalPath& key) const {
            uint32_t hashCode = key.id * 31;
            if (key.mirrorRootId != UNASSIGNED_LAYER_ID) {
                hashCode += key.mirrorRootId * 31;
            }
            return std::hash<size_t>{}(hashCode);
        }
    };

    // Helper class to add nodes to an existing traversal id and removes the
    // node when it goes out of scope.
    class ScopedAddToTraversalPath {
    public:
        ScopedAddToTraversalPath(TraversalPath& traversalPath, uint32_t layerId,
                                 LayerHierarchy::Variant variantArg);
        ~ScopedAddToTraversalPath();

    private:
        TraversalPath& mTraversalPath;
        TraversalPath mParentPath;
    };
    LayerHierarchy(RequestedLayerState* layer);

    // Visitor function that provides the hierarchy node and a traversal id which uniquely
    // identifies how was visited. The hierarchy contains a pointer to the RequestedLayerState.
    // Return false to stop traversing down the hierarchy.
    typedef std::function<bool(const LayerHierarchy& hierarchy,
                               const LayerHierarchy::TraversalPath& traversalPath)>
            Visitor;

    // Traverse the hierarchy and visit all child variants.
    void traverse(const Visitor& visitor) const {
        TraversalPath root = TraversalPath::ROOT;
        if (mLayer) {
            root.id = mLayer->id;
        }
        traverse(visitor, root);
    }

    // Traverse the hierarchy in z-order, skipping children that have relative parents.
    void traverseInZOrder(const Visitor& visitor) const {
        TraversalPath root = TraversalPath::ROOT;
        if (mLayer) {
            root.id = mLayer->id;
        }
        traverseInZOrder(visitor, root);
    }

    const RequestedLayerState* getLayer() const;
    const LayerHierarchy* getRelativeParent() const;
    const LayerHierarchy* getParent() const;
    std::string getDebugString(const char* prefix = "") const;
    std::string getDebugStringShort() const;
    // Traverse the hierarchy and return true if loops are found. The outInvalidRelativeRoot
    // will contain the first relative root that was visited twice in a traversal.
    bool hasRelZLoop(uint32_t& outInvalidRelativeRoot) const;
    std::vector<std::pair<LayerHierarchy*, Variant>> mChildren;

private:
    friend LayerHierarchyBuilder;
    LayerHierarchy(const LayerHierarchy& hierarchy, bool childrenOnly);
    void addChild(LayerHierarchy*, LayerHierarchy::Variant);
    void removeChild(LayerHierarchy*);
    void sortChildrenByZOrder();
    void updateChild(LayerHierarchy*, LayerHierarchy::Variant);
    void traverseInZOrder(const Visitor& visitor, LayerHierarchy::TraversalPath& parent) const;
    void traverse(const Visitor& visitor, LayerHierarchy::TraversalPath& parent) const;

    const RequestedLayerState* mLayer;
    LayerHierarchy* mParent = nullptr;
    LayerHierarchy* mRelativeParent = nullptr;
};

// Given a list of RequestedLayerState, this class will build a root hierarchy and an
// offscreen hierarchy. The builder also has an update method which can update an existing
// hierarchy from a list of RequestedLayerState and associated change flags.
class LayerHierarchyBuilder {
public:
    LayerHierarchyBuilder(const std::vector<std::unique_ptr<RequestedLayerState>>&);
    void update(const std::vector<std::unique_ptr<RequestedLayerState>>& layers,
                const std::vector<std::unique_ptr<RequestedLayerState>>& destroyedLayers);
    LayerHierarchy getPartialHierarchy(uint32_t, bool childrenOnly) const;
    const LayerHierarchy& getHierarchy() const;
    const LayerHierarchy& getOffscreenHierarchy() const;
    std::string getDebugString(uint32_t layerId, uint32_t depth = 0) const;

private:
    void onLayerAdded(RequestedLayerState* layer);
    void attachToParent(LayerHierarchy*);
    void detachFromParent(LayerHierarchy*);
    void attachToRelativeParent(LayerHierarchy*);
    void detachFromRelativeParent(LayerHierarchy*);
    void attachHierarchyToRelativeParent(LayerHierarchy*);
    void detachHierarchyFromRelativeParent(LayerHierarchy*);

    void onLayerDestroyed(RequestedLayerState* layer);
    void updateMirrorLayer(RequestedLayerState* layer);
    LayerHierarchy* getHierarchyFromId(uint32_t layerId, bool crashOnFailure = true);
    std::unordered_map<uint32_t, LayerHierarchy*> mLayerIdToHierarchy;
    std::vector<std::unique_ptr<LayerHierarchy>> mHierarchies;
    LayerHierarchy mRoot{nullptr};
    LayerHierarchy mOffscreenRoot{nullptr};
};

} // namespace android::surfaceflinger::frontend
