// 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.

#ifndef MPACT_SIM_GENERIC_SIMPLE_RESOURCE_H_
#define MPACT_SIM_GENERIC_SIMPLE_RESOURCE_H_

#include <list>
#include <string>
#include <vector>

#include "absl/container/flat_hash_map.h"
#include "absl/status/status.h"
#include "absl/status/statusor.h"
#include "absl/strings/string_view.h"
#include "mpact/sim/generic/resource_bitset.h"

namespace mpact {
namespace sim {
namespace generic {

// A simple resource belongs to a SimpleResourcePool. It can be in two
// states: reserved or free, indicated by a single bit (1 - reserved, 0 - free)
// in a bit vector. While the exact semantics of reserved and free depends on
// the underlying use of the classes, the initial intended use is to have
// reserved mean that a write is pending to a register or an empty fifo to
// indicate when to stall (or hold) issue of an instruction due to RAW (or WAW)
// dependencies. A SimpleResource instance can be attached to a the object it
// represents so that the object can mark the resource free (or reserved) based
// on the state of the object. For instance, for a register/fifo, the instance
// may Release() the resource when the write lands.

// A SimpleResource is part of a SimpleResourcePool that represents the set of
// resources as a bit vector. This makes it easy to specify a set of required
// resources as a SimpleResourceSet and test for availability with bitwise AND.

// A SimpleResourceSet can be associated with an instruction to indicate the set
// of resources that must be available prior to issue. The issue logic then
// tests against the resource pool to see if any of the required resources are
// reserved or not.

class SimpleResourcePool;

// The SimpleResource class models a single simulated resource that can have
// two states: free or reserved. It is "simple" because it cannot be reserved
// for cycles in the future. Any reserve/free action takes effect immediately.
class SimpleResource {
  friend class SimpleResourcePool;

 private:
  // The constructor is private. It is called from a SimpleResourcePool
  // instance in which the resource belongs.
  SimpleResource(absl::string_view name, int index, SimpleResourcePool* pool);
  SimpleResource() = delete;
  virtual ~SimpleResource() = default;

 public:
  // Mark the resource reserved in the associated resource pool.
  void Acquire();
  // Mark the resource free in the associated resource pool.
  void Release();
  // Return true if the resource is not marked reserved in the associated
  // resource pool.
  bool IsFree() const;

  // Returns the "one hot" bitvector for the resource.
  const ResourceBitSet& resource_bit() const { return resource_bit_; }

  // The bit index of the resource in the bitvector.
  int index() const { return index_; }

  // Other accessors.
  const std::string& name() const { return name_; }
  const SimpleResourcePool* pool() const { return pool_; }

 private:
  ResourceBitSet resource_bit_;
  std::string name_;
  int index_;
  SimpleResourcePool* pool_;
};

// The SimpleResourceSet models a set of individual SimpleResources that are
// reserved/released/checked (CanReserve()) at the same time.
class SimpleResourceSet {
  friend class SimpleResourcePool;

 private:
  explicit SimpleResourceSet(SimpleResourcePool*);
  SimpleResourceSet() = delete;
  virtual ~SimpleResourceSet() = default;

 public:
  // Adds the resource to the resource set. Return error if the resource
  // belongs to a different pool.
  absl::Status AddResource(SimpleResource* resource);
  absl::Status AddResource(absl::string_view name);

  // Mark the resources in the set reserved in the associated resource pool.
  void Acquire();

  // Mark the resources free in the associated resource pool.
  void Release();

  // Return true if the resource set is not marked reserved in the associated
  // resource pool.
  bool IsFree() const;

  std::string AsString() const;

  // Return the bit vector for the resources in this set.
  const ResourceBitSet& resource_vector() const { return resource_vector_; }

 private:
  ResourceBitSet resource_vector_;
  SimpleResourcePool* pool_;
};

// The SimpleResourcePool is a class for managing a group of SimpleResource
// instances. The resource pool is meant to group together resources that
// typically would be checked/reserved/freed at the same.
class SimpleResourcePool {
 public:
  // Create a named resource pool with the given maximum size.
  SimpleResourcePool(absl::string_view name, int width);
  SimpleResourcePool() = delete;
  virtual ~SimpleResourcePool();

  // Add a named resource to the resource pool. This will assign the resource
  // an index in the set of named resources in the pool.
  absl::Status AddResource(absl::string_view name);

  // Return the SimpleResource pointer of the named resource, or nullptr if it
  // hasn't been added.
  SimpleResource* GetResource(absl::string_view name) const;
  // Return the SimpleResource pointer of resource with bit index 'index', or
  // nullptr if it hasn't been added.
  SimpleResource* GetResource(unsigned index) const;
  // If the resource does not exisit, add it. Return a pointer to the named
  // resource.
  SimpleResource* GetOrAddResource(absl::string_view name);
  // Create an resource set for the current resource pool.
  SimpleResourceSet* CreateResourceSet();

  // Return true if the resources in the resource/resource set are not reserved
  // in the resource pool.
  bool IsFree(const SimpleResourceSet* resource_set) const;
  bool IsFree(const SimpleResource* resource) const;

  // Mark the resource/resource set reserved in the resource pool.
  void Acquire(const SimpleResourceSet* resource_set);
  void Acquire(const SimpleResource* resource);

  // Mark the resource/resource set unreserved in the resource pool.
  void Release(const SimpleResourceSet* resource_set);
  void Release(const SimpleResource* resource);

  // List reserved resources as string.
  std::string ReservedAsString() const;

  // Accessors.
  const std::string& name() const { return name_; }
  const ResourceBitSet& resource_vector() const { return resource_vector_; }

  // The width is the max number of resources (i.e., bitwidth of the resource
  // vector).
  unsigned width() const { return width_; }

 private:
  absl::StatusOr<SimpleResource*> AddResourceInternal(absl::string_view name);
  absl::flat_hash_map<std::string, SimpleResource*> resource_name_map_;
  std::vector<SimpleResource*> resources_;
  std::list<SimpleResourceSet*> resource_sets_;
  ResourceBitSet resource_vector_;
  std::string name_;
  unsigned width_;
};

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

#endif  // MPACT_SIM_GENERIC_SIMPLE_RESOURCE_H_
