// Copyright 2021 The Tint 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_TINT_RESOLVER_DEPENDENCY_GRAPH_H_
#define SRC_TINT_RESOLVER_DEPENDENCY_GRAPH_H_

#include <string>
#include <vector>

#include "src/tint/ast/module.h"
#include "src/tint/builtin/access.h"
#include "src/tint/builtin/builtin.h"
#include "src/tint/builtin/builtin_value.h"
#include "src/tint/builtin/function.h"
#include "src/tint/builtin/interpolation_sampling.h"
#include "src/tint/builtin/interpolation_type.h"
#include "src/tint/builtin/texel_format.h"
#include "src/tint/diagnostic/diagnostic.h"
#include "src/tint/symbol_table.h"
#include "src/tint/utils/hashmap.h"

namespace tint::resolver {

/// UnresolvedIdentifier is the variant value used by ResolvedIdentifier
struct UnresolvedIdentifier {
    /// Name of the unresolved identifier
    std::string name;
};

/// ResolvedIdentifier holds the resolution of an ast::Identifier.
/// Can hold one of:
/// - UnresolvedIdentifier
/// - const ast::TypeDecl*  (as const ast::Node*)
/// - const ast::Variable*  (as const ast::Node*)
/// - const ast::Function*  (as const ast::Node*)
/// - builtin::Function
/// - builtin::Access
/// - builtin::AddressSpace
/// - builtin::Builtin
/// - builtin::BuiltinValue
/// - builtin::InterpolationSampling
/// - builtin::InterpolationType
/// - builtin::TexelFormat
class ResolvedIdentifier {
  public:
    /// Constructor
    /// @param value the resolved identifier value
    template <typename T>
    ResolvedIdentifier(T value) : value_(value) {}  // NOLINT(runtime/explicit)

    /// @return the UnresolvedIdentifier if the identifier was not resolved
    const UnresolvedIdentifier* Unresolved() const {
        if (auto n = std::get_if<UnresolvedIdentifier>(&value_)) {
            return n;
        }
        return nullptr;
    }

    /// @return the node pointer if the ResolvedIdentifier holds an AST node, otherwise nullptr
    const ast::Node* Node() const {
        if (auto n = std::get_if<const ast::Node*>(&value_)) {
            return *n;
        }
        return nullptr;
    }

    /// @return the builtin function if the ResolvedIdentifier holds builtin::Function, otherwise
    /// builtin::Function::kNone
    builtin::Function BuiltinFunction() const {
        if (auto n = std::get_if<builtin::Function>(&value_)) {
            return *n;
        }
        return builtin::Function::kNone;
    }

    /// @return the access if the ResolvedIdentifier holds builtin::Access, otherwise
    /// builtin::Access::kUndefined
    builtin::Access Access() const {
        if (auto n = std::get_if<builtin::Access>(&value_)) {
            return *n;
        }
        return builtin::Access::kUndefined;
    }

    /// @return the address space if the ResolvedIdentifier holds builtin::AddressSpace, otherwise
    /// builtin::AddressSpace::kUndefined
    builtin::AddressSpace AddressSpace() const {
        if (auto n = std::get_if<builtin::AddressSpace>(&value_)) {
            return *n;
        }
        return builtin::AddressSpace::kUndefined;
    }

    /// @return the builtin type if the ResolvedIdentifier holds builtin::Builtin, otherwise
    /// builtin::Builtin::kUndefined
    builtin::Builtin BuiltinType() const {
        if (auto n = std::get_if<builtin::Builtin>(&value_)) {
            return *n;
        }
        return builtin::Builtin::kUndefined;
    }

    /// @return the builtin value if the ResolvedIdentifier holds builtin::BuiltinValue, otherwise
    /// builtin::BuiltinValue::kUndefined
    builtin::BuiltinValue BuiltinValue() const {
        if (auto n = std::get_if<builtin::BuiltinValue>(&value_)) {
            return *n;
        }
        return builtin::BuiltinValue::kUndefined;
    }

    /// @return the texel format if the ResolvedIdentifier holds type::InterpolationSampling,
    /// otherwise type::InterpolationSampling::kUndefined
    builtin::InterpolationSampling InterpolationSampling() const {
        if (auto n = std::get_if<builtin::InterpolationSampling>(&value_)) {
            return *n;
        }
        return builtin::InterpolationSampling::kUndefined;
    }

    /// @return the texel format if the ResolvedIdentifier holds type::InterpolationType,
    /// otherwise type::InterpolationType::kUndefined
    builtin::InterpolationType InterpolationType() const {
        if (auto n = std::get_if<builtin::InterpolationType>(&value_)) {
            return *n;
        }
        return builtin::InterpolationType::kUndefined;
    }

    /// @return the texel format if the ResolvedIdentifier holds type::TexelFormat, otherwise
    /// type::TexelFormat::kUndefined
    builtin::TexelFormat TexelFormat() const {
        if (auto n = std::get_if<builtin::TexelFormat>(&value_)) {
            return *n;
        }
        return builtin::TexelFormat::kUndefined;
    }

    /// @param value the value to compare the ResolvedIdentifier to
    /// @return true if the ResolvedIdentifier is equal to @p value
    template <typename T>
    bool operator==(const T& value) const {
        if (auto n = std::get_if<T>(&value_)) {
            return *n == value;
        }
        return false;
    }

    /// @param other the other value to compare to this
    /// @return true if this ResolvedIdentifier and @p other are not equal
    template <typename T>
    bool operator!=(const T& other) const {
        return !(*this == other);
    }

    /// @param symbols the program's symbol table
    /// @param diagnostics diagnostics used to report ICEs
    /// @return a description of the resolved symbol
    std::string String(const SymbolTable& symbols, diag::List& diagnostics) const;

  private:
    std::variant<UnresolvedIdentifier,
                 const ast::Node*,
                 builtin::Function,
                 builtin::Access,
                 builtin::AddressSpace,
                 builtin::Builtin,
                 builtin::BuiltinValue,
                 builtin::InterpolationSampling,
                 builtin::InterpolationType,
                 builtin::TexelFormat>
        value_;
};

/// DependencyGraph holds information about module-scope declaration dependency
/// analysis and symbol resolutions.
struct DependencyGraph {
    /// Constructor
    DependencyGraph();
    /// Move-constructor
    DependencyGraph(DependencyGraph&&);
    /// Destructor
    ~DependencyGraph();

    /// Build() performs symbol resolution and dependency analysis on `module`,
    /// populating `output` with the resulting dependency graph.
    /// @param module the AST module to analyse
    /// @param symbols the symbol table
    /// @param diagnostics the diagnostic list to populate with errors / warnings
    /// @param output the resulting DependencyGraph
    /// @returns true on success, false on error
    static bool Build(const ast::Module& module,
                      const SymbolTable& symbols,
                      diag::List& diagnostics,
                      DependencyGraph& output);

    /// All globals in dependency-sorted order.
    utils::Vector<const ast::Node*, 32> ordered_globals;

    /// Map of ast::Identifier to a ResolvedIdentifier
    utils::Hashmap<const ast::Identifier*, ResolvedIdentifier, 64> resolved_identifiers;

    /// Map of ast::Variable to a type, function, or variable that is shadowed by
    /// the variable key. A declaration (X) shadows another (Y) if X and Y use
    /// the same symbol, and X is declared in a sub-scope of the scope that
    /// declares Y.
    utils::Hashmap<const ast::Variable*, const ast::Node*, 16> shadows;
};

}  // namespace tint::resolver

#endif  // SRC_TINT_RESOLVER_DEPENDENCY_GRAPH_H_
