/**
 * Auto-generated execution implementation for core ChiMod
 * Implements Container virtual APIs (Run, Del, SaveTask, LoadTask, NewCopy, Aggregate)
 * using switch-case dispatch
 * 
 * This file is autogenerated - do not edit manually.
 * Changes should be made to the autogen tool or the YAML configuration.
 */

#include "wrp_cae/core/core_runtime.h"
#include "wrp_cae/core/autogen/core_methods.h"
#include <chimaera/chimaera.h>

namespace wrp_cae::core {

//==============================================================================
// Container Virtual API Implementations
//==============================================================================

void Runtime::Init(const chi::PoolId &pool_id, const std::string &pool_name,
                   chi::u32 container_id) {
  // Call base class initialization
  chi::Container::Init(pool_id, pool_name, container_id);

  // Initialize the client for this ChiMod
  client_ = Client(pool_id);
}

void Runtime::Run(chi::u32 method, hipc::FullPtr<chi::Task> task_ptr, chi::RunContext& rctx) {
  switch (method) {
    case Method::kCreate: {
      Create(task_ptr.Cast<CreateTask>(), rctx);
      break;
    }
    case Method::kDestroy: {
      Destroy(task_ptr.Cast<DestroyTask>(), rctx);
      break;
    }
    case Method::kParseOmni: {
      ParseOmni(task_ptr.Cast<ParseOmniTask>(), rctx);
      break;
    }
    default: {
      // Unknown method - do nothing
      break;
    }
  }
}

void Runtime::Del(chi::u32 method, hipc::FullPtr<chi::Task> task_ptr) {
  // Use IPC manager to deallocate task from shared memory
  auto* ipc_manager = CHI_IPC;

  switch (method) {
    case Method::kCreate: {
      ipc_manager->DelTask(task_ptr.Cast<CreateTask>());
      break;
    }
    case Method::kDestroy: {
      ipc_manager->DelTask(task_ptr.Cast<DestroyTask>());
      break;
    }
    case Method::kParseOmni: {
      ipc_manager->DelTask(task_ptr.Cast<ParseOmniTask>());
      break;
    }
    default: {
      // For unknown methods, still try to delete from main segment
      ipc_manager->DelTask(task_ptr);
      break;
    }
  }
}

chi::u64 Runtime::GetWorkRemaining() const {
  // Return 0 indicating no pending work for this container
  // This can be enhanced in the future to track actual pending tasks
  return 0;
}

void Runtime::SaveTask(chi::u32 method, chi::SaveTaskArchive& archive, 
                        hipc::FullPtr<chi::Task> task_ptr) {
  switch (method) {
    case Method::kCreate: {
      auto typed_task = task_ptr.Cast<CreateTask>();
      archive << *typed_task;
      break;
    }
    case Method::kDestroy: {
      auto typed_task = task_ptr.Cast<DestroyTask>();
      archive << *typed_task;
      break;
    }
    case Method::kParseOmni: {
      auto typed_task = task_ptr.Cast<ParseOmniTask>();
      archive << *typed_task;
      break;
    }
    default: {
      // Unknown method - do nothing
      break;
    }
  }
}

void Runtime::LoadTask(chi::u32 method, chi::LoadTaskArchive& archive, 
                        hipc::FullPtr<chi::Task>& task_ptr) {
  auto* ipc_manager = CHI_IPC;
  
  switch (method) {
    case Method::kCreate: {
      // Allocate task using typed NewTask if not already allocated
      if (task_ptr.IsNull()) {
        task_ptr = ipc_manager->NewTask<CreateTask>().template Cast<chi::Task>();
      }
      auto typed_task = task_ptr.Cast<CreateTask>();
      archive >> *typed_task;
      break;
    }
    case Method::kDestroy: {
      // Allocate task using typed NewTask if not already allocated
      if (task_ptr.IsNull()) {
        task_ptr = ipc_manager->NewTask<DestroyTask>().template Cast<chi::Task>();
      }
      auto typed_task = task_ptr.Cast<DestroyTask>();
      archive >> *typed_task;
      break;
    }
    case Method::kParseOmni: {
      // Allocate task using typed NewTask if not already allocated
      if (task_ptr.IsNull()) {
        task_ptr = ipc_manager->NewTask<ParseOmniTask>().template Cast<chi::Task>();
      }
      auto typed_task = task_ptr.Cast<ParseOmniTask>();
      archive >> *typed_task;
      break;
    }
    default: {
      // Unknown method - do nothing
      break;
    }
  }
}

void Runtime::NewCopy(chi::u32 method, const hipc::FullPtr<chi::Task>& orig_task,
                       hipc::FullPtr<chi::Task>& dup_task, bool deep) {
  auto* ipc_manager = CHI_IPC;
  if (!ipc_manager) {
    return;
  }
  
  switch (method) {
    case Method::kCreate: {
      // Allocate new task using SHM default constructor
      auto typed_task = ipc_manager->NewTask<CreateTask>();
      if (!typed_task.IsNull()) {
        // Copy base Task fields first
        typed_task.template Cast<chi::Task>()->Copy(orig_task);
        // Then copy task-specific fields
        typed_task->Copy(orig_task.Cast<CreateTask>());
        // Cast to base Task type for return
        dup_task = typed_task.template Cast<chi::Task>();
      }
      break;
    }
    case Method::kDestroy: {
      // Allocate new task using SHM default constructor
      auto typed_task = ipc_manager->NewTask<DestroyTask>();
      if (!typed_task.IsNull()) {
        // Copy base Task fields first
        typed_task.template Cast<chi::Task>()->Copy(orig_task);
        // Then copy task-specific fields
        typed_task->Copy(orig_task.Cast<DestroyTask>());
        // Cast to base Task type for return
        dup_task = typed_task.template Cast<chi::Task>();
      }
      break;
    }
    case Method::kParseOmni: {
      // Allocate new task using SHM default constructor
      auto typed_task = ipc_manager->NewTask<ParseOmniTask>();
      if (!typed_task.IsNull()) {
        // Copy base Task fields first
        typed_task.template Cast<chi::Task>()->Copy(orig_task);
        // Then copy task-specific fields
        typed_task->Copy(orig_task.Cast<ParseOmniTask>());
        // Cast to base Task type for return
        dup_task = typed_task.template Cast<chi::Task>();
      }
      break;
    }
    default: {
      // For unknown methods, create base Task copy
      auto typed_task = ipc_manager->NewTask<chi::Task>();
      if (!typed_task.IsNull()) {
        typed_task->Copy(orig_task);
        dup_task = typed_task;  // Already chi::Task type
      }
      break;
    }
  }
  
  (void)deep;    // Deep copy parameter reserved for future use
}

void Runtime::Aggregate(chi::u32 method, hipc::FullPtr<chi::Task> origin_task,
                         hipc::FullPtr<chi::Task> replica_task) {
  switch (method) {
    case Method::kCreate: {
      auto typed_origin = origin_task.Cast<CreateTask>();
      auto typed_replica = replica_task.Cast<CreateTask>();
      // Call base Task aggregate to propagate return codes
      origin_task->Aggregate(replica_task);
      // Use SFINAE-based macro to call task-specific Aggregate if available, otherwise Copy
      CHI_AGGREGATE_OR_COPY(typed_origin, typed_replica);
      break;
    }
    case Method::kDestroy: {
      auto typed_origin = origin_task.Cast<DestroyTask>();
      auto typed_replica = replica_task.Cast<DestroyTask>();
      // Call base Task aggregate to propagate return codes
      origin_task->Aggregate(replica_task);
      // Use SFINAE-based macro to call task-specific Aggregate if available, otherwise Copy
      CHI_AGGREGATE_OR_COPY(typed_origin, typed_replica);
      break;
    }
    case Method::kParseOmni: {
      auto typed_origin = origin_task.Cast<ParseOmniTask>();
      auto typed_replica = replica_task.Cast<ParseOmniTask>();
      // Call base Task aggregate to propagate return codes
      origin_task->Aggregate(replica_task);
      // Use SFINAE-based macro to call task-specific Aggregate if available, otherwise Copy
      CHI_AGGREGATE_OR_COPY(typed_origin, typed_replica);
      break;
    }
    default: {
      // For unknown methods, use base Task Aggregate (which also propagates return codes)
      origin_task->Aggregate(replica_task);
      break;
    }
  }
}

} // namespace wrp_cae::core
