// Copyright 2023 Google LLC
//
// 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
//
//     https://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.

#include "mpact/sim/generic/complex_resource_operand.h"

#include <cstddef>
#include <cstdint>
#include <cstring>

#include "absl/status/status.h"
#include "absl/strings/str_cat.h"
#include "absl/types/span.h"

namespace mpact {
namespace sim {
namespace generic {

// Sets the bits in the bit_array_ array for the cycles, starting at begin and
// ending at end. Bits are counted from lsb to msb [(63..0), (127..64), (191,
// 128),..] etc.
absl::Status ComplexResourceOperand::SetCycleMask(size_t begin, size_t end) {
  // If the resource is null return an error.
  if (resource_ == nullptr) {
    return absl::InternalError("Resource is null in ComplexResourceOperand");
  }
  // If the start cycle is after the end cycle, return an error.
  if (begin > end) {
    return absl::InvalidArgumentError(absl::StrCat(
        "Begin cycle (", begin, ") is greater than end cycle (", end, ")"));
  }
  // If the end cycle is beyond the cycle depth of the resource, return an
  // error.
  if (end >= resource_->cycle_depth()) {
    return absl::InvalidArgumentError(absl::StrCat(
        "ComplexResourceOperand for resource '", resource_->name(), "': end(",
        end, ") is greater than cycle depth (", resource_->cycle_depth()));
  }
  // Compute the size of the array needed.
  span_size_ = (end + 63) / 64;
  // Delete any previous allocation.
  delete[] bit_array_;
  // Allocate the array and clear the bytes.
  bit_array_ = new uint64_t[span_size_];
  memset(bit_array_, 0, span_size_ * 8);
  // Set the bits in [begin, end].
  for (size_t i = begin; i <= end; i++) {
    int word_index = i >> 6;
    int bit_index = i & 0x3f;
    bit_array_[word_index] |= 1ULL << bit_index;
  }
  return absl::OkStatus();
}

absl::Status ComplexResourceOperand::SetCycleMask(
    absl::Span<const uint64_t> span) {
  // If the resource is null, return an error.
  if (resource_ == nullptr) {
    return absl::InternalError("Resource is null in ComplexResourceOperand");
  }
  // If the span is too long, return an error.
  if (resource_->bit_array().size() < span.size()) {
    return absl::InvalidArgumentError("Span too long for cycle mask");
  }

  span_size_ = span.size();
  // See if there are any bits set beyond the cycle depth of the resource.
  size_t mod = resource_->cycle_depth() & 0x3f;
  if (span[span_size_ - 1] >> mod) {
    return absl::InvalidArgumentError(
        absl::StrCat("Bits set beyond the cycle depth of resource '",
                     resource_->name(), "'"));
  }
  // Make sure that there are some bits set in the span.
  uint64_t or_value = 0;
  for (uint64_t value : span) {
    or_value |= value;
  }
  if (or_value == 0) {
    return absl::InvalidArgumentError("No bits set in input span");
  }
  // Delete any previous allocation.
  delete[] bit_array_;
  // Allocate the array and copy the span.
  bit_array_ = new uint64_t[span_size_];
  for (int i = 0; i < span_size_; i++) {
    bit_array_[i] = span[i];
  }
  return absl::OkStatus();
}

}  // namespace generic
}  // namespace sim
}  // namespace mpact
