/*
 * Copyright 2026 WebAssembly Community Group participants
 *
 * 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 wasm_support_span_h
#define wasm_support_span_h

#include <algorithm>
#include <cassert>
#include <cstdint>
#include <iostream>
#include <limits>

#include "support/inplace_vector.h"

namespace wasm {

// A span of values.
//
// Span{min, max} means [min, max], inclusive of both sides. To represent an
// empty span, we use min > max.
template<typename T> struct Span {
  static constexpr T Min = std::numeric_limits<T>::lowest();
  static constexpr T Max = std::numeric_limits<T>::max();

  T min = Min;
  T max = Max;

  constexpr Span() = default;
  constexpr Span(T min, T max) : min(min), max(max) {}

  // Set a single value as possible.
  void set(T value) { min = max = value; }

  // To represent an empty span, we use min > max, an impossible span.
  void setEmpty() {
    *this = empty();
    assert(isEmpty());
  }

  bool isEmpty() const { return min > max; }

  static Span<T> empty() { return Span{Max, Min}; }

  void setFull() {
    *this = Span();
    assert(isFull());
  }

  bool isFull() const { return min == Min && max == Max; }

  static Span<T> full() { return Span{}; }

  // Intersect this with another span, returning a (possibly empty) span.
  Span<T> intersection(const Span& other) const {
    if (isEmpty() || other.isEmpty()) {
      return empty();
    }
    return Span<T>{std::max(min, other.min), std::min(max, other.max)};
  }

  // Checks whether two spans have any overlap at all.
  bool hasOverlap(const Span& other) const {
    return !intersection(other).isEmpty();
  }

  // Check whether we contain another span (possibly being equal).
  bool contains(const Span& other) const {
    return intersection(other) == other;
  }

  bool operator==(const Span& other) const {
    if (isEmpty()) {
      return other.isEmpty();
    }
    return !other.isEmpty() && min == other.min && max == other.max;
  }
  bool operator!=(const Span& other) const { return !(*this == other); }
};

// A union of spans, which we assume are disjoint.
template<typename T, size_t N>
struct Spans : public inplace_vector<Span<T>, N> {
  constexpr Spans() = default;

  // Initialize with Spans.
  Spans(std::initializer_list<Span<T>> init) {
    for (const auto& span : init) {
      this->push_back(span);
    }
  }

  bool hasOverlap(const Spans<T, N>& other) const {
    // There is overlap if any of our spans overlaps with any of other's.
    for (const auto& span : *this) {
      for (const auto& otherSpan : other) {
        if (span.hasOverlap(otherSpan)) {
          return true;
        }
      }
    }
    return false;
  }

  bool contains(const Spans<T, N>& other) const {
    // We contain other if each of their spans is contained in us.
    for (const auto& otherSpan : other) {
      // Because our spans are assumed to be disjoint, exactly one of our
      // spans must contain otherSpan.
      bool found = false;
      for (const auto& span : *this) {
        if (span.contains(otherSpan)) {
          found = true;
          break;
        }
      }
      if (!found) {
        return false;
      }
    }
    return true;
  }
};

// A useful set of 2 spans that can contain any integer value. 2 spans is enough
// to contain spans for any inequality, signed or unsigned: we represent numbers
// as unsigned internally, and so e.g. signed x <= 10 ends up as two disjoint
// spans, [0..10] and [2^31..MAX_INT].
using SpansU2 = Spans<uint64_t, 2>;

template<typename T>
inline std::ostream& operator<<(std::ostream& os, const Span<T>& span) {
  if (span.isEmpty()) {
    return os << "[empty]";
  }
  return os << '[' << span.min << ", " << span.max << ']';
}

template<typename T, size_t N>
inline std::ostream& operator<<(std::ostream& os, const Spans<T, N>& spans) {
  if (spans.empty()) {
    return os << "{empty}";
  }
  os << '{';
  for (size_t i = 0; i < spans.size(); ++i) {
    if (i > 0) {
      os << ", ";
    }
    os << spans[i];
  }
  return os << '}';
}

} // namespace wasm

#endif // wasm_support_span_h
