// 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 enclosing loop construct, if one exists. A construct
  /// encloses itself.
  const Construct* const enclosing_loop = nullptr;
  /// The nearest enclosing continue construct, if one exists. A construct
  /// encloses itself.
  const Construct* const enclosing_continue = nullptr;
  /// The nearest enclosing loop construct or continue construct or
  /// switch-selection construct, if one exists. The signficance is
  /// that a high level language "break" will branch to the merge block
  /// of such an enclosing construct.
  /// A construct encloses itself.
  const Construct* const enclosing_loop_or_continue_or_switch = 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_loop) {
    o << " in-l:" << ToStringBrief(c.enclosing_loop);
  }

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

  if ((c.enclosing_loop_or_continue_or_switch != c.enclosing_loop) &&
      (c.enclosing_loop_or_continue_or_switch != c.enclosing_continue)) {
    o << " in-c-l-s:" << ToStringBrief(c.enclosing_loop_or_continue_or_switch);
  }

  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_
