// Copyright 2020 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_READER_SPIRV_CONSTRUCT_H_
#define SRC_READER_SPIRV_CONSTRUCT_H_

#include <cstdint>
#include <memory>
#include <ostream>
#include <sstream>
#include <vector>

namespace tint {
namespace reader {
namespace spirv {

/// A structured construct, consisting of a set of basic blocks.
/// A construct is a span of blocks in the computed block order,
/// and will appear contiguously in the WGSL source.
struct Construct {
  /// Enumeration for the kinds of structured constructs.
  enum Kind {
    /// The whole function.
    kFunction,
    /// A SPIR-V selection construct, header ending in OpBrancConditional
    kIfSelection,
    /// A SPIR-V selection construct, header ending in OpSwitch
    kSwitchSelection,
    /// A SPIR-V loop construct
    kLoop,
    /// A SPIR-V continue construct
    kContinue,
  };

  /// Constructor
  /// @param the_parent parent construct
  /// @param the_depth construct nesting depth
  /// @param the_kind construct kind
  /// @param the_begin_id block id of the first block in the construct
  /// @param the_end_id block id of the first block after the construct, or 0
  /// @param the_begin_pos block order position of the_begin_id
  /// @param the_end_pos block order position of the_end_id or a too-large value
  Construct(const Construct* the_parent,
            int the_depth,
            Kind the_kind,
            uint32_t the_begin_id,
            uint32_t the_end_id,
            uint32_t the_begin_pos,
            uint32_t the_end_pos);

  /// @param pos a block position
  /// @returns true if the given block position is inside this construct.
  bool ContainsPos(uint32_t pos) const {
    return begin_pos <= pos && pos < end_pos;
  }

  /// The nearest enclosing construct (other than itself), or nullptr if
  /// this construct represents the entire function.
  const Construct* const parent = nullptr;
  /// The nearest continue construct, if one exists. A construct encloses
  /// itself.
  const Construct* const enclosing_continue = nullptr;
  /// The nearest enclosing loop or continue construct, if one exists.
  /// A construct encloses itself.
  const Construct* const enclosing_loop_or_continue = nullptr;

  /// Control flow nesting depth. The entry block is at nesting depth 0.
  const int depth = 0;
  /// The construct kind
  const Kind kind = kFunction;
  /// The id of the first block in this structure.
  const uint32_t begin_id = 0;
  /// 0 for kFunction, or the id of the block immediately after this construct
  /// in the computed block order.
  const uint32_t end_id = 0;
  /// The position of block |begin_id| in the computed block order.
  const uint32_t begin_pos = 0;
  /// The position of block |end_id| in the block order, or the number of
  /// block order elements if |end_id| is 0.
  const uint32_t end_pos = 0;
};

using ConstructList = std::vector<std::unique_ptr<Construct>>;

/// Converts a construct kind to a string.
/// @param kind the construct kind to convert
/// @returns the string representation
inline std::string ToString(Construct::Kind kind) {
  switch (kind) {
    case Construct::kFunction:
      return "Function";
    case Construct::kIfSelection:
      return "IfSelection";
    case Construct::kSwitchSelection:
      return "SwitchSelection";
    case Construct::kLoop:
      return "Loop";
    case Construct::kContinue:
      return "Continue";
  }
  return "NONE";
}

/// Converts a construct into a short summary string.
/// @param c the construct, which can be null
/// @returns a short summary string
inline std::string ToStringBrief(const Construct* c) {
  if (c) {
    std::stringstream ss;
    ss << ToString(c->kind) << "@" << c->begin_id;
    return ss.str();
  }
  return "null";
}

/// Emits a construct to a stream.
/// @param o the stream
/// @param c the structured construct
/// @returns the stream
inline std::ostream& operator<<(std::ostream& o, const Construct& c) {
  o << "Construct{ " << ToString(c.kind) << " [" << c.begin_pos << ","
    << c.end_pos << ")"
    << " begin_id:" << c.begin_id << " end_id:" << c.end_id
    << " depth:" << c.depth;

  o << " parent:" << ToStringBrief(c.parent);

  if (c.enclosing_continue) {
    o << " in-c:" << ToStringBrief(c.enclosing_continue);
  }

  if (c.enclosing_loop_or_continue != c.enclosing_continue) {
    o << " in-c-l:" << ToStringBrief(c.enclosing_loop_or_continue);
  }

  o << " }";
  return o;
}

/// Emits a construct to a stream.
/// @param o the stream
/// @param c the structured construct
/// @returns the stream
inline std::ostream& operator<<(std::ostream& o,
                                const std::unique_ptr<Construct>& c) {
  return o << *(c.get());
}

/// Converts a construct to a string.
/// @param c the construct
/// @returns the string representation
inline std::string ToString(const Construct& c) {
  std::stringstream ss;
  ss << c;
  return ss.str();
}

/// Converts a unique pointer to a construct to a string.
/// @param c the construct
/// @returns the string representation
inline std::string ToString(const std::unique_ptr<Construct>& c) {
  return ToString(*(c.get()));
}

/// Emits a construct list to a stream.
/// @param o the stream
/// @param cl the construct list
/// @returns the stream
inline std::ostream& operator<<(std::ostream& o, const ConstructList& cl) {
  o << "ConstructList{\n";
  for (const auto& c : cl) {
    o << "  " << c << "\n";
  }
  o << "}";
  return o;
}

/// Converts a construct list to a string.
/// @param cl the construct list
/// @returns the string representation
inline std::string ToString(const ConstructList& cl) {
  std::stringstream ss;
  ss << cl;
  return ss.str();
}

}  // namespace spirv
}  // namespace reader
}  // namespace tint

#endif  // SRC_READER_SPIRV_CONSTRUCT_H_
