/*
 Do not modify, auto-generated by classes.py

 Copyright 2019 Alain Dargelas

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

/*
 * File:   instance.h
 * Author:
 *
 * Created on December 14, 2019, 10:03 PM
 */

#ifndef UHDM_INSTANCE_H
#define UHDM_INSTANCE_H

#include <uhdm/sv_vpi_user.h>
#include <uhdm/uhdm_vpi_user.h>

#include <uhdm/containers.h>
#include <uhdm/scope.h>

#include "assertion.h"


namespace UHDM {
class instance;
class module_inst;

class instance : public scope {
  UHDM_IMPLEMENT_RTTI(instance, scope)
public:
  // Implicit constructor used to initialize all members,
  // comment: instance();
  virtual ~instance() = default;

  virtual bool VpiDefName(std::string_view data) final;
  virtual std::string_view VpiDefName() const final;

  bool VpiArrayMember() const { return vpiArrayMember_; }
  bool VpiArrayMember(bool data) {
    vpiArrayMember_ = data;
    return true;
  }

  bool VpiCellInstance() const { return vpiCellInstance_; }
  bool VpiCellInstance(bool data) {
    vpiCellInstance_ = data;
    return true;
  }

  int32_t VpiDefNetType() const { return vpiDefNetType_; }
  bool VpiDefNetType(int32_t data) {
    vpiDefNetType_ = data;
    return true;
  }

  bool VpiDefFile(std::string_view data);
  std::string_view VpiDefFile() const;

  int32_t VpiDefLineNo() const { return vpiDefLineNo_; }
  bool VpiDefLineNo(int32_t data) {
    vpiDefLineNo_ = data;
    return true;
  }

  int32_t VpiDefDelayMode() const { return vpiDefDelayMode_; }
  bool VpiDefDelayMode(int32_t data) {
    vpiDefDelayMode_ = data;
    return true;
  }

  bool VpiProtected() const { return vpiProtected_; }
  bool VpiProtected(bool data) {
    vpiProtected_ = data;
    return true;
  }

  int32_t VpiTimePrecision() const { return vpiTimePrecision_; }
  bool VpiTimePrecision(int32_t data) {
    vpiTimePrecision_ = data;
    return true;
  }

  int32_t VpiTimeUnit() const { return vpiTimeUnit_; }
  bool VpiTimeUnit(int32_t data) {
    vpiTimeUnit_ = data;
    return true;
  }

  int32_t VpiUnconnDrive() const { return vpiUnconnDrive_; }
  bool VpiUnconnDrive(int32_t data) {
    vpiUnconnDrive_ = data;
    return true;
  }

  bool VpiLibrary(std::string_view data);
  std::string_view VpiLibrary() const;

  bool VpiCell(std::string_view data);
  std::string_view VpiCell() const;

  bool VpiConfig(std::string_view data);
  std::string_view VpiConfig() const;

  bool VpiAutomatic() const { return vpiAutomatic_; }
  bool VpiAutomatic(bool data) {
    vpiAutomatic_ = data;
    return true;
  }

  bool VpiTop() const { return vpiTop_; }
  bool VpiTop(bool data) {
    vpiTop_ = data;
    return true;
  }

  VectorOfprogram* Programs() const { return programs_; }
  bool Programs(VectorOfprogram* data) {
    programs_ = data;
    return true;
  }

  VectorOfprogram* Program_arrays() const { return program_arrays_; }
  bool Program_arrays(VectorOfprogram* data) {
    program_arrays_ = data;
    return true;
  }

  VectorOfclass_defn* Class_defns() const { return class_defns_; }
  bool Class_defns(VectorOfclass_defn* data) {
    class_defns_ = data;
    return true;
  }

  VectorOftask_func* Task_funcs() const { return task_funcs_; }
  bool Task_funcs(VectorOftask_func* data) {
    task_funcs_ = data;
    return true;
  }

  VectorOfnet* Nets() const { return nets_; }
  bool Nets(VectorOfnet* data) {
    nets_ = data;
    return true;
  }

  VectorOfarray_net* Array_nets() const { return array_nets_; }
  bool Array_nets(VectorOfarray_net* data) {
    array_nets_ = data;
    return true;
  }

  VectorOfspec_param* Spec_params() const { return spec_params_; }
  bool Spec_params(VectorOfspec_param* data) {
    spec_params_ = data;
    return true;
  }

  VectorOfany* Assertions() const { return assertions_; }
  bool Assertions(VectorOfany* data) {
    if (!assertionGroupCompliant(data)) return false;
    assertions_ = data;
    return true;
  }

  module_inst* Module_inst()  { return module_inst_; }
  const module_inst* Module_inst() const { return module_inst_; }
  template <typename T>
  T* Module_inst() {
    return (module_inst_ == nullptr) ? nullptr : any_cast<T*>(module_inst_);
  }
  template <typename T>
  const T* Module_inst() const {
    return (module_inst_ == nullptr) ? nullptr : any_cast<const T*>(module_inst_);
  }
  bool Module_inst(module_inst* data) {
    module_inst_ = data;
    return true;
  }

  instance* Instance()  { return instance_; }
  const instance* Instance() const { return instance_; }
  template <typename T>
  T* Instance() {
    return (instance_ == nullptr) ? nullptr : any_cast<T*>(instance_);
  }
  template <typename T>
  const T* Instance() const {
    return (instance_ == nullptr) ? nullptr : any_cast<const T*>(instance_);
  }
  bool Instance(instance* data) {
    instance_ = data;
    return true;
  }

  virtual instance* DeepClone(BaseClass* parent, CloneContext* context) const override = 0;

  virtual const BaseClass* GetByVpiName(std::string_view name) const override;

  virtual std::tuple<const BaseClass*, UHDM_OBJECT_TYPE, const std::vector<const BaseClass*>*> GetByVpiType(int32_t type) const override;

  virtual vpi_property_value_t GetVpiPropertyValue(int32_t property) const override;

  virtual int32_t Compare(const BaseClass* other, CompareContext* context) const override;

  virtual  UHDM_OBJECT_TYPE UhdmType() const override { return UHDM_OBJECT_TYPE::uhdminstance; }

protected:
  void DeepCopy(instance* clone, BaseClass* parent, CloneContext* context) const;

private:
  SymbolId vpiDefName_;

  bool vpiArrayMember_ = false;

  bool vpiCellInstance_ = false;

  int32_t vpiDefNetType_ = 0;

  SymbolId vpiDefFile_;

  int32_t vpiDefLineNo_ = 0;

  int32_t vpiDefDelayMode_ = 0;

  bool vpiProtected_ = false;

  int32_t vpiTimePrecision_ = 0;

  int32_t vpiTimeUnit_ = 0;

  int32_t vpiUnconnDrive_ = 0;

  SymbolId vpiLibrary_;

  SymbolId vpiCell_;

  SymbolId vpiConfig_;

  bool vpiAutomatic_ = false;

  bool vpiTop_ = false;

  VectorOfprogram* programs_ = nullptr;

  VectorOfprogram* program_arrays_ = nullptr;

  VectorOfclass_defn* class_defns_ = nullptr;

  VectorOftask_func* task_funcs_ = nullptr;

  VectorOfnet* nets_ = nullptr;

  VectorOfarray_net* array_nets_ = nullptr;

  VectorOfspec_param* spec_params_ = nullptr;

  VectorOfany* assertions_ = nullptr;

  module_inst* module_inst_ = nullptr;

  instance* instance_ = nullptr;
};

#if 0 // This class cannot be instantiated
typedef FactoryT<instance> instanceFactory;
#endif

typedef FactoryT<std::vector<instance *>> VectorOfinstanceFactory;

}  // namespace UHDM

#endif
