// Copyright 2025 The IREE Authors
//
// Licensed under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception

#include <stdio.h>

#include "iree/base/api.h"
#include "iree/base/tooling/flags.h"
#include "iree/hal/api.h"
#include "iree/hal/replay/recorder.h"
#include "iree/io/file_handle.h"
#include "iree/io/formats/irpa/irpa_builder.h"
#include "iree/io/parameter_index.h"
#include "iree/io/parameter_index_provider.h"
#include "iree/io/scope_map.h"
#include "iree/io/stream.h"
#include "iree/modules/hal/module.h"
#include "iree/tooling/context_util.h"
#include "iree/tooling/function_util.h"
#include "iree/tooling/parameter_util.h"
#include "iree/vm/api.h"

//===----------------------------------------------------------------------===//
// Flags
//===----------------------------------------------------------------------===//

IREE_FLAG(bool, list_targets, false,
          "Lists the targets an encoding module can produce parameters for and "
          "exit.");

IREE_FLAG(bool, list_parameters, false,
          "Lists the parameters that will be encoded and exit.");

IREE_FLAG(string, target, "",
          "Target to use for encoding. If not specified, uses auto-detection.");

IREE_FLAG(bool, quiet, false,
          "Suppress output except for errors. Exit code indicates success.");

IREE_FLAG_LIST(string, output,
               "Specifies an output parameter file per scope.\n"
               "Format: `scope=path.irpa` or `path.irpa` for default scope.\n"
               "Example: `--output=encoded=output.irpa`");

//===----------------------------------------------------------------------===//
// Encoder target discovery
//===----------------------------------------------------------------------===//

// Encoder function set for a single target.
typedef struct iree_encode_target_t {
  iree_string_view_t target;
  iree_vm_function_t indices_fn;
  iree_vm_function_t steps_fn;
  iree_vm_function_t encode_fn;
} iree_encode_target_t;

// Storage for discovered encoder targets.
typedef struct iree_encode_target_set_t {
  iree_vm_function_t detect_target_fn;
  iree_host_size_t target_count;
  iree_host_size_t target_capacity;
  iree_encode_target_t* targets;
  iree_allocator_t allocator;
} iree_encode_target_set_t;

static void iree_encode_target_set_initialize(
    iree_allocator_t allocator, iree_encode_target_set_t* out_target_set) {
  memset(out_target_set, 0, sizeof(*out_target_set));
  out_target_set->allocator = allocator;
}

static void iree_encode_target_set_deinitialize(
    iree_encode_target_set_t* target_set) {
  if (target_set->targets) {
    iree_allocator_free(target_set->allocator, target_set->targets);
  }
  memset(target_set, 0, sizeof(*target_set));
}

static iree_status_t iree_encode_target_set_add(
    iree_encode_target_set_t* target_set, iree_string_view_t target_name,
    iree_encode_target_t** out_target) {
  // Check if target already exists.
  for (iree_host_size_t i = 0; i < target_set->target_count; ++i) {
    if (iree_string_view_equal(target_set->targets[i].target, target_name)) {
      *out_target = &target_set->targets[i];
      return iree_ok_status();
    }
  }
  // Grow if needed.
  if (target_set->target_count >= target_set->target_capacity) {
    iree_host_size_t new_capacity =
        target_set->target_capacity ? target_set->target_capacity * 2 : 4;
    IREE_RETURN_IF_ERROR(iree_allocator_realloc(
        target_set->allocator, new_capacity * sizeof(iree_encode_target_t),
        (void**)&target_set->targets));
    target_set->target_capacity = new_capacity;
  }
  // Add new target.
  iree_encode_target_t* target = &target_set->targets[target_set->target_count];
  memset(target, 0, sizeof(*target));
  target->target = target_name;
  ++target_set->target_count;
  *out_target = target;
  return iree_ok_status();
}

// Looks up a reflection attribute value by key.
static iree_string_view_t iree_encode_lookup_reflection_attr(
    iree_vm_function_t* function, iree_string_view_t key) {
  return iree_vm_function_lookup_attr_by_name(function, key);
}

// Discovers encoder functions from the module by scanning exported function
// attributes.
static iree_status_t iree_encode_discover_functions(
    iree_vm_module_t* module, iree_encode_target_set_t* target_set) {
  IREE_TRACE_ZONE_BEGIN(z0);

  iree_vm_module_signature_t signature = iree_vm_module_signature(module);

  for (iree_host_size_t i = 0; i < signature.export_function_count; ++i) {
    iree_vm_function_t function;
    IREE_RETURN_AND_END_ZONE_IF_ERROR(
        z0, iree_vm_module_lookup_function_by_ordinal(
                module, IREE_VM_FUNCTION_LINKAGE_EXPORT, i, &function));

    // Check for iree.encode.function attribute.
    iree_string_view_t encode_function = iree_encode_lookup_reflection_attr(
        &function, IREE_SV("iree.encode.function"));
    if (iree_string_view_is_empty(encode_function)) continue;

    if (iree_string_view_equal(encode_function, IREE_SV("detect_target"))) {
      target_set->detect_target_fn = function;
    } else {
      // Get target name for indices/steps/encode functions.
      iree_string_view_t target_name = iree_encode_lookup_reflection_attr(
          &function, IREE_SV("iree.encode.target"));
      if (iree_string_view_is_empty(target_name)) {
        IREE_TRACE_ZONE_END(z0);
        return iree_make_status(IREE_STATUS_INVALID_ARGUMENT,
                                "encoder function missing iree.encode.target");
      }

      iree_encode_target_t* target = NULL;
      IREE_RETURN_AND_END_ZONE_IF_ERROR(
          z0, iree_encode_target_set_add(target_set, target_name, &target));

      if (iree_string_view_equal(encode_function, IREE_SV("indices"))) {
        target->indices_fn = function;
      } else if (iree_string_view_equal(encode_function, IREE_SV("steps"))) {
        target->steps_fn = function;
      } else if (iree_string_view_equal(encode_function, IREE_SV("encode"))) {
        target->encode_fn = function;
      }
    }
  }

  IREE_TRACE_ZONE_END(z0);
  return iree_ok_status();
}

//===----------------------------------------------------------------------===//
// Output scope/archive types
//===----------------------------------------------------------------------===//

typedef struct iree_output_scope_t {
  iree_string_view_t scope;
  iree_string_view_t path;
} iree_output_scope_t;

typedef struct iree_output_scope_list_t {
  iree_host_size_t count;
  iree_output_scope_t* entries;
  iree_allocator_t allocator;
} iree_output_scope_list_t;

static void iree_output_scope_list_initialize(iree_allocator_t allocator,
                                              iree_output_scope_list_t* list) {
  memset(list, 0, sizeof(*list));
  list->allocator = allocator;
}

static void iree_output_scope_list_deinitialize(
    iree_output_scope_list_t* list) {
  if (list->entries) {
    iree_allocator_free(list->allocator, list->entries);
  }
  memset(list, 0, sizeof(*list));
}

// Archive context for a single output scope.
typedef struct iree_output_archive_t {
  iree_string_view_t scope;
  iree_string_view_t path;
  iree_io_parameter_archive_builder_t builder;
  iree_io_file_handle_t* file_handle;
  iree_io_parameter_index_t* index;
  iree_io_parameter_provider_t* provider;
} iree_output_archive_t;

static void iree_output_archive_deinitialize(iree_output_archive_t* archive) {
  iree_io_parameter_provider_release(archive->provider);
  iree_io_parameter_index_release(archive->index);
  iree_io_file_handle_release(archive->file_handle);
  iree_io_parameter_archive_builder_deinitialize(&archive->builder);
}

//===----------------------------------------------------------------------===//
// Load modules and discover encoder functions
//===----------------------------------------------------------------------===//

static iree_status_t iree_encode_load_and_discover(
    iree_vm_instance_t* instance, iree_allocator_t host_allocator,
    iree_tooling_module_list_t* out_module_list,
    iree_vm_module_t** out_encoder_module,
    iree_encode_target_set_t* out_target_set) {
  IREE_TRACE_ZONE_BEGIN(z0);

  iree_tooling_module_list_initialize(out_module_list);
  iree_encode_target_set_initialize(host_allocator, out_target_set);

  // Load modules from flags.
  IREE_RETURN_AND_END_ZONE_IF_ERROR(
      z0, iree_tooling_load_modules_from_flags(instance, host_allocator,
                                               out_module_list));

  if (out_module_list->count == 0) {
    IREE_TRACE_ZONE_END(z0);
    return iree_make_status(IREE_STATUS_INVALID_ARGUMENT,
                            "no modules specified; use --module=path.vmfb");
  }

  // Encoder module is the last module (by convention).
  *out_encoder_module = out_module_list->values[out_module_list->count - 1];

  // Discover encoder functions.
  IREE_RETURN_AND_END_ZONE_IF_ERROR(
      z0, iree_encode_discover_functions(*out_encoder_module, out_target_set));

  if (out_target_set->target_count == 0) {
    IREE_TRACE_ZONE_END(z0);
    return iree_make_status(
        IREE_STATUS_NOT_FOUND,
        "no encoder functions found in module; ensure the module was produced "
        "by iree-compile with --iree-parameter-encoder-output-file");
  }

  IREE_TRACE_ZONE_END(z0);
  return iree_ok_status();
}

//===----------------------------------------------------------------------===//
// Select target
//===----------------------------------------------------------------------===//

static iree_status_t iree_encode_select_target(
    iree_encode_target_set_t* target_set,
    iree_encode_target_t** out_selected_target) {
  iree_string_view_t target_flag = iree_make_cstring_view(FLAG_target);

  if (iree_string_view_is_empty(target_flag)) {
    // Use first target.
    *out_selected_target = &target_set->targets[0];
    return iree_ok_status();
  }

  // Find matching target.
  for (iree_host_size_t i = 0; i < target_set->target_count; ++i) {
    if (iree_string_view_equal(target_set->targets[i].target, target_flag)) {
      *out_selected_target = &target_set->targets[i];
      return iree_ok_status();
    }
  }

  return iree_make_status(IREE_STATUS_NOT_FOUND,
                          "target '%s' not found in encoder module; "
                          "use --list-targets to see available targets",
                          FLAG_target);
}

static iree_status_t iree_encode_validate_target(iree_encode_target_t* target) {
  if (!target->indices_fn.module) {
    return iree_make_status(IREE_STATUS_NOT_FOUND,
                            "indices function not found for target '%.*s'; "
                            "encoder module may be incomplete",
                            (int)target->target.size, target->target.data);
  }
  if (!target->encode_fn.module) {
    return iree_make_status(IREE_STATUS_NOT_FOUND,
                            "encode function not found for target '%.*s'; "
                            "encoder module may be incomplete",
                            (int)target->target.size, target->target.data);
  }
  return iree_ok_status();
}

//===----------------------------------------------------------------------===//
// --list_targets implementation
//===----------------------------------------------------------------------===//

static iree_status_t iree_encode_print_targets(
    iree_vm_module_t* encoder_module, iree_encode_target_set_t* target_set) {
  iree_string_view_t module_name = iree_vm_module_name(encoder_module);
  fprintf(stdout, "Encoder module: %.*s\n", (int)module_name.size,
          module_name.data);
  fprintf(stdout, "Available targets:\n");

  for (iree_host_size_t i = 0; i < target_set->target_count; ++i) {
    iree_encode_target_t* target = &target_set->targets[i];
    fprintf(stdout, "  %.*s\n", (int)target->target.size, target->target.data);

    iree_string_view_t scopes = iree_encode_lookup_reflection_attr(
        &target->indices_fn, IREE_SV("iree.encode.scopes"));
    if (!iree_string_view_is_empty(scopes)) {
      fprintf(stdout, "    scopes: %.*s\n", (int)scopes.size, scopes.data);
    }
  }

  return iree_ok_status();
}

//===----------------------------------------------------------------------===//
// Call indices function
//===----------------------------------------------------------------------===//

// Creates a temporary context and calls the indices function.
// The indices function returns constant data and doesn't need parameters.
// TODO(benvanik): Consider calling without full context if function has no
// imports.
static iree_status_t iree_encode_call_indices(
    iree_vm_instance_t* instance, iree_tooling_module_list_t* module_list,
    iree_encode_target_t* target, iree_allocator_t host_allocator,
    iree_vm_list_t** out_indices_list) {
  IREE_TRACE_ZONE_BEGIN(z0);

  iree_vm_context_t* context = NULL;
  iree_hal_device_list_t* device_list = NULL;
  iree_hal_replay_recorder_t* replay_recorder = NULL;
  IREE_RETURN_AND_END_ZONE_IF_ERROR(
      z0, iree_tooling_create_context_from_flags(
              instance, module_list->count, module_list->values,
              /*default_device_uri=*/iree_string_view_empty(), host_allocator,
              &context, &device_list, /*out_device_allocator=*/NULL,
              &replay_recorder));

  // Invoke indices function.
  iree_vm_list_t* outputs = NULL;
  iree_status_t status = iree_vm_list_create(iree_vm_make_undefined_type_def(),
                                             1, host_allocator, &outputs);
  if (iree_status_is_ok(status)) {
    status = iree_vm_invoke(
        context, target->indices_fn, IREE_VM_INVOCATION_FLAG_NONE,
        /*policy=*/NULL, /*inputs=*/NULL, outputs, host_allocator);
  }

  // Extract result list.
  if (iree_status_is_ok(status)) {
    iree_vm_ref_t list_ref = iree_vm_ref_null();
    status = iree_vm_list_get_ref_assign(outputs, 0, &list_ref);
    if (iree_status_is_ok(status)) {
      *out_indices_list = iree_vm_list_deref(list_ref);
      if (*out_indices_list) {
        iree_vm_list_retain(*out_indices_list);
      }
    }
  }

  iree_vm_list_release(outputs);
  iree_vm_context_release(context);
  if (replay_recorder) {
    status = iree_status_join(
        status,
        iree_status_annotate_f(iree_hal_replay_recorder_close(replay_recorder),
                               "closing HAL replay capture"));
    iree_hal_replay_recorder_release(replay_recorder);
  }
  iree_hal_device_list_free(device_list);

  IREE_TRACE_ZONE_END(z0);
  return status;
}

//===----------------------------------------------------------------------===//
// --list_parameters implementation
//===----------------------------------------------------------------------===//

static iree_status_t iree_encode_print_parameters(
    iree_vm_list_t* indices_list) {
  iree_host_size_t scope_count = iree_vm_list_size(indices_list);

  for (iree_host_size_t scope_i = 0; scope_i < scope_count; ++scope_i) {
    iree_vm_ref_t scope_struct_ref = iree_vm_ref_null();
    if (!iree_status_is_ok(iree_vm_list_get_ref_assign(indices_list, scope_i,
                                                       &scope_struct_ref))) {
      continue;
    }
    iree_vm_list_t* scope_struct = iree_vm_list_deref(scope_struct_ref);
    if (!scope_struct || iree_vm_list_size(scope_struct) < 2) continue;

    // Get scope name.
    iree_vm_ref_t scope_name_ref = iree_vm_ref_null();
    iree_vm_list_get_ref_assign(scope_struct, 0, &scope_name_ref);
    iree_vm_buffer_t* scope_name_buffer = iree_vm_buffer_deref(scope_name_ref);
    iree_string_view_t scope_name =
        scope_name_buffer ? iree_vm_buffer_as_string(scope_name_buffer)
                          : IREE_SV("<default>");

    fprintf(stdout, "Scope: \"%.*s\"\n", (int)scope_name.size, scope_name.data);

    // Get entries list.
    iree_vm_ref_t entries_ref = iree_vm_ref_null();
    iree_vm_list_get_ref_assign(scope_struct, 1, &entries_ref);
    iree_vm_list_t* entries = iree_vm_list_deref(entries_ref);
    if (!entries) continue;

    // Print each entry.
    iree_host_size_t entry_count = iree_vm_list_size(entries);
    for (iree_host_size_t entry_i = 0; entry_i < entry_count; ++entry_i) {
      iree_vm_ref_t entry_ref = iree_vm_ref_null();
      if (!iree_status_is_ok(
              iree_vm_list_get_ref_assign(entries, entry_i, &entry_ref))) {
        continue;
      }
      iree_vm_list_t* entry = iree_vm_list_deref(entry_ref);
      if (!entry || iree_vm_list_size(entry) < 5) continue;

      iree_vm_value_t type_value, length_value;
      iree_vm_list_get_value(entry, 0, &type_value);
      iree_vm_list_get_value(entry, 3, &length_value);

      iree_vm_ref_t key_ref = iree_vm_ref_null();
      iree_vm_list_get_ref_assign(entry, 1, &key_ref);
      iree_vm_buffer_t* key_buffer = iree_vm_buffer_deref(key_ref);
      iree_string_view_t key = key_buffer ? iree_vm_buffer_as_string(key_buffer)
                                          : IREE_SV("<unknown>");

      if (type_value.i64 == 0) {
        // SPLAT entry.
        iree_vm_value_t pattern_value, pattern_length_value;
        iree_vm_list_get_value(entry, 4, &pattern_value);
        iree_vm_list_get_value(entry, 5, &pattern_length_value);
        fprintf(stdout,
                "  %.*s: SPLAT, %" PRIu64 " bytes, pattern=0x%0*" PRIx64 "\n",
                (int)key.size, key.data, (uint64_t)length_value.i64,
                (int)pattern_length_value.i64 * 2, (uint64_t)pattern_value.i64);
      } else {
        // DATA entry.
        iree_vm_value_t alignment_value;
        iree_vm_list_get_value(entry, 4, &alignment_value);
        fprintf(stdout,
                "  %.*s: DATA, %" PRIu64 " bytes, alignment %" PRIu64 "\n",
                (int)key.size, key.data, (uint64_t)length_value.i64,
                (uint64_t)alignment_value.i64);
      }
    }
  }

  return iree_ok_status();
}

//===----------------------------------------------------------------------===//
// Parse output flags
//===----------------------------------------------------------------------===//

static iree_status_t iree_encode_parse_output_flags(
    iree_output_scope_list_t* list) {
  iree_host_size_t count = FLAG_output_list().count;
  if (count == 0) return iree_ok_status();

  IREE_RETURN_IF_ERROR(iree_allocator_malloc(
      list->allocator, count * sizeof(iree_output_scope_t),
      (void**)&list->entries));
  list->count = count;

  for (iree_host_size_t i = 0; i < count; ++i) {
    iree_string_view_t flag = FLAG_output_list().values[i];
    iree_string_view_t scope, path;
    if (iree_string_view_split(flag, '=', &scope, &path) == -1) {
      // No scope provided - use empty scope.
      path = scope;
      scope = iree_string_view_empty();
    }
    list->entries[i].scope = scope;
    list->entries[i].path = path;
  }

  return iree_ok_status();
}

//===----------------------------------------------------------------------===//
// Create output archives
//===----------------------------------------------------------------------===//

// Parses parameter indices and populates archive builders.
static iree_status_t iree_encode_parse_indices_into_archives(
    iree_vm_list_t* indices_list, iree_output_archive_t* archives,
    iree_host_size_t archive_count) {
  IREE_TRACE_ZONE_BEGIN(z0);

  iree_host_size_t scope_count = iree_vm_list_size(indices_list);
  for (iree_host_size_t scope_i = 0; scope_i < scope_count; ++scope_i) {
    // Get scope struct: [scope_name, entries_list].
    iree_vm_ref_t scope_struct_ref = iree_vm_ref_null();
    IREE_RETURN_AND_END_ZONE_IF_ERROR(
        z0,
        iree_vm_list_get_ref_assign(indices_list, scope_i, &scope_struct_ref));
    iree_vm_list_t* scope_struct = iree_vm_list_deref(scope_struct_ref);
    if (!scope_struct || iree_vm_list_size(scope_struct) < 2) {
      IREE_TRACE_ZONE_END(z0);
      return iree_make_status(IREE_STATUS_INVALID_ARGUMENT,
                              "invalid scope struct in indices");
    }

    // Get scope name.
    iree_vm_ref_t scope_name_ref = iree_vm_ref_null();
    IREE_RETURN_AND_END_ZONE_IF_ERROR(
        z0, iree_vm_list_get_ref_assign(scope_struct, 0, &scope_name_ref));
    iree_vm_buffer_t* scope_name_buffer = iree_vm_buffer_deref(scope_name_ref);
    iree_string_view_t scope_name =
        scope_name_buffer ? iree_vm_buffer_as_string(scope_name_buffer)
                          : iree_string_view_empty();

    // Find matching archive.
    iree_output_archive_t* archive = NULL;
    for (iree_host_size_t j = 0; j < archive_count; ++j) {
      if (iree_string_view_equal(archives[j].scope, scope_name)) {
        archive = &archives[j];
        break;
      }
    }
    if (!archive) continue;  // Scope not in output list.

    // Get entries list.
    iree_vm_ref_t entries_ref = iree_vm_ref_null();
    IREE_RETURN_AND_END_ZONE_IF_ERROR(
        z0, iree_vm_list_get_ref_assign(scope_struct, 1, &entries_ref));
    iree_vm_list_t* entries = iree_vm_list_deref(entries_ref);
    if (!entries) {
      IREE_TRACE_ZONE_END(z0);
      return iree_make_status(IREE_STATUS_INVALID_ARGUMENT,
                              "invalid entries in scope struct");
    }

    // Process each parameter entry.
    iree_host_size_t entry_count = iree_vm_list_size(entries);
    for (iree_host_size_t entry_i = 0; entry_i < entry_count; ++entry_i) {
      iree_vm_ref_t entry_ref = iree_vm_ref_null();
      IREE_RETURN_AND_END_ZONE_IF_ERROR(
          z0, iree_vm_list_get_ref_assign(entries, entry_i, &entry_ref));
      iree_vm_list_t* entry = iree_vm_list_deref(entry_ref);
      if (!entry || iree_vm_list_size(entry) < 5) {
        IREE_TRACE_ZONE_END(z0);
        return iree_make_status(IREE_STATUS_INVALID_ARGUMENT,
                                "invalid entry in entries list");
      }

      // Parse entry fields: [type, key, metadata, length, ...].
      iree_vm_value_t type_value, length_value;
      IREE_RETURN_AND_END_ZONE_IF_ERROR(
          z0, iree_vm_list_get_value(entry, 0, &type_value));

      iree_vm_ref_t key_ref = iree_vm_ref_null();
      IREE_RETURN_AND_END_ZONE_IF_ERROR(
          z0, iree_vm_list_get_ref_assign(entry, 1, &key_ref));
      iree_vm_buffer_t* key_buffer = iree_vm_buffer_deref(key_ref);
      if (!key_buffer) {
        IREE_TRACE_ZONE_END(z0);
        return iree_make_status(IREE_STATUS_INVALID_ARGUMENT,
                                "parameter entry missing key");
      }
      iree_string_view_t key = iree_vm_buffer_as_string(key_buffer);

      iree_vm_ref_t metadata_ref = iree_vm_ref_null();
      iree_vm_list_get_ref_assign(entry, 2, &metadata_ref);
      iree_vm_buffer_t* metadata_buffer = iree_vm_buffer_deref(metadata_ref);
      iree_const_byte_span_t metadata = iree_const_byte_span_empty();
      if (metadata_buffer) {
        metadata = iree_vm_buffer_const_contents(metadata_buffer);
      }

      IREE_RETURN_AND_END_ZONE_IF_ERROR(
          z0, iree_vm_list_get_value(entry, 3, &length_value));
      uint64_t length = (uint64_t)length_value.i64;

      if (type_value.i64 == 0) {
        // SPLAT entry: [type, key, metadata, length, pattern, pattern_length].
        iree_vm_value_t pattern_value, pattern_length_value;
        IREE_RETURN_AND_END_ZONE_IF_ERROR(
            z0, iree_vm_list_get_value(entry, 4, &pattern_value));
        IREE_RETURN_AND_END_ZONE_IF_ERROR(
            z0, iree_vm_list_get_value(entry, 5, &pattern_length_value));

        uint64_t pattern = (uint64_t)pattern_value.i64;
        IREE_RETURN_AND_END_ZONE_IF_ERROR(
            z0, iree_io_parameter_archive_builder_add_splat_entry(
                    &archive->builder, key, metadata, &pattern,
                    (uint8_t)pattern_length_value.i64, length));
      } else {
        // DATA entry: [type, key, metadata, length, alignment].
        iree_vm_value_t alignment_value;
        IREE_RETURN_AND_END_ZONE_IF_ERROR(
            z0, iree_vm_list_get_value(entry, 4, &alignment_value));

        IREE_RETURN_AND_END_ZONE_IF_ERROR(
            z0, iree_io_parameter_archive_builder_add_data_entry(
                    &archive->builder, key, metadata,
                    (uint64_t)alignment_value.i64, length));
      }
    }
  }

  IREE_TRACE_ZONE_END(z0);
  return iree_ok_status();
}

// Creates archive files and providers for each output scope.
static iree_status_t iree_encode_create_archives(
    iree_vm_list_t* indices_list, iree_output_scope_list_t* output_list,
    iree_allocator_t host_allocator, iree_output_archive_t** out_archives) {
  IREE_TRACE_ZONE_BEGIN(z0);

  // Allocate archive array.
  iree_output_archive_t* archives = NULL;
  IREE_RETURN_AND_END_ZONE_IF_ERROR(
      z0,
      iree_allocator_malloc(host_allocator,
                            output_list->count * sizeof(iree_output_archive_t),
                            (void**)&archives));

  // Initialize archive builders.
  iree_status_t status = iree_ok_status();
  for (iree_host_size_t i = 0; i < output_list->count; ++i) {
    memset(&archives[i], 0, sizeof(archives[i]));
    archives[i].scope = output_list->entries[i].scope;
    archives[i].path = output_list->entries[i].path;
    status = iree_io_parameter_archive_builder_initialize(host_allocator,
                                                          &archives[i].builder);
    if (!iree_status_is_ok(status)) break;
  }

  // Parse indices into archive builders.
  if (iree_status_is_ok(status)) {
    status = iree_encode_parse_indices_into_archives(indices_list, archives,
                                                     output_list->count);
  }

  // Create files and write headers.
  if (iree_status_is_ok(status)) {
    for (iree_host_size_t i = 0; i < output_list->count; ++i) {
      iree_output_archive_t* archive = &archives[i];

      iree_io_physical_size_t archive_size =
          iree_io_parameter_archive_builder_total_size(&archive->builder);

      // Create null-terminated path.
      char* path_cstr = NULL;
      status = iree_allocator_malloc(host_allocator, archive->path.size + 1,
                                     (void**)&path_cstr);
      if (!iree_status_is_ok(status)) break;
      memcpy(path_cstr, archive->path.data, archive->path.size);
      path_cstr[archive->path.size] = '\0';

      // Create the output file with a synchronous handle for header writes and
      // an async handle for HAL queue transfers into the parameter storage.
      iree_io_file_handle_t* stream_file_handle = NULL;
      status = iree_io_file_handle_create(
          IREE_IO_FILE_MODE_READ | IREE_IO_FILE_MODE_WRITE |
              IREE_IO_FILE_MODE_SHARE_READ | IREE_IO_FILE_MODE_SHARE_WRITE,
          iree_make_cstring_view(path_cstr), archive_size, host_allocator,
          &stream_file_handle);
      if (iree_status_is_ok(status)) {
        status = iree_io_file_handle_open(
            IREE_IO_FILE_MODE_READ | IREE_IO_FILE_MODE_WRITE |
                IREE_IO_FILE_MODE_SHARE_READ | IREE_IO_FILE_MODE_SHARE_WRITE |
                IREE_IO_FILE_MODE_ASYNC,
            iree_make_cstring_view(path_cstr), host_allocator,
            &archive->file_handle);
      }
      iree_allocator_free(host_allocator, path_cstr);
      if (!iree_status_is_ok(status)) {
        iree_io_file_handle_release(stream_file_handle);
        break;
      }

      // Create stream and index.
      iree_io_stream_t* stream = NULL;
      status =
          iree_io_stream_open(IREE_IO_STREAM_MODE_WRITABLE, stream_file_handle,
                              0, host_allocator, &stream);

      if (!iree_status_is_ok(status)) {
        iree_io_file_handle_release(stream_file_handle);
        break;
      }

      status = iree_io_parameter_index_create(host_allocator, &archive->index);
      if (!iree_status_is_ok(status)) {
        iree_io_stream_release(stream);
        iree_io_file_handle_release(stream_file_handle);
        break;
      }

      // Write archive header.
      status = iree_io_parameter_archive_builder_write(
          &archive->builder, archive->file_handle, 0, stream, archive->index);
      iree_io_stream_release(stream);
      iree_io_file_handle_release(stream_file_handle);
      if (!iree_status_is_ok(status)) break;

      // Create provider backed by the archive.
      status = iree_io_parameter_index_provider_create(
          archive->scope, archive->index,
          IREE_IO_PARAMETER_INDEX_PROVIDER_DEFAULT_MAX_CONCURRENT_OPERATIONS,
          host_allocator, &archive->provider);
      if (!iree_status_is_ok(status)) break;
    }
  }

  if (!iree_status_is_ok(status)) {
    for (iree_host_size_t i = 0; i < output_list->count; ++i) {
      iree_output_archive_deinitialize(&archives[i]);
    }
    iree_allocator_free(host_allocator, archives);
    IREE_TRACE_ZONE_END(z0);
    return status;
  }

  *out_archives = archives;
  IREE_TRACE_ZONE_END(z0);
  return iree_ok_status();
}

//===----------------------------------------------------------------------===//
// Create encoding context with output providers
//===----------------------------------------------------------------------===//

// Creates the encoding context with output providers attached.
// TODO(benvanik): Allow adding providers to existing parameters module to avoid
// recreating context.
static iree_status_t iree_encode_create_encoding_context(
    iree_vm_instance_t* instance, iree_tooling_module_list_t* module_list,
    iree_output_archive_t* archives, iree_host_size_t archive_count,
    iree_allocator_t host_allocator, iree_vm_context_t** out_context,
    iree_hal_device_list_t** out_device_list,
    iree_hal_replay_recorder_t** out_replay_recorder) {
  IREE_ASSERT_ARGUMENT(out_context);
  IREE_ASSERT_ARGUMENT(out_device_list);
  IREE_ASSERT_ARGUMENT(out_replay_recorder);
  *out_context = NULL;
  *out_device_list = NULL;
  *out_replay_recorder = NULL;
  IREE_TRACE_ZONE_BEGIN(z0);

  // Collect output providers.
  iree_host_size_t provider_count = 0;
  for (iree_host_size_t i = 0; i < archive_count; ++i) {
    if (archives[i].provider) ++provider_count;
  }

  iree_io_parameter_provider_t** providers =
      (iree_io_parameter_provider_t**)iree_alloca(
          provider_count * sizeof(iree_io_parameter_provider_t*));
  for (iree_host_size_t i = 0, j = 0; i < archive_count; ++i) {
    if (archives[i].provider) {
      providers[j++] = archives[i].provider;
    }
  }

  // Create parameters module with output providers.
  iree_vm_module_t* params_module = NULL;
  iree_status_t status = iree_tooling_create_parameters_module_from_flags(
      instance, provider_count, providers, host_allocator, &params_module);

  // Pre-populate resolved_list with params module so resolver won't create
  // default.
  iree_tooling_module_list_t resolved_list;
  iree_tooling_module_list_initialize(&resolved_list);

  if (iree_status_is_ok(status)) {
    status = iree_tooling_module_list_push_back(&resolved_list, params_module);
  }

  // Resolve dependencies (adds HAL, etc.).
  if (iree_status_is_ok(status)) {
    iree_hal_device_list_t* device_list = NULL;
    iree_hal_replay_recorder_t* replay_recorder = NULL;
    status = iree_tooling_resolve_modules(
        instance, module_list->count, module_list->values,
        /*default_device_uri=*/iree_string_view_empty(), host_allocator,
        &resolved_list, &device_list, /*out_device_allocator=*/NULL,
        &replay_recorder);

    // Create context.
    iree_vm_context_t* context = NULL;
    if (iree_status_is_ok(status)) {
      status = iree_vm_context_create_with_modules(
          instance, IREE_VM_CONTEXT_FLAG_NONE, resolved_list.count,
          resolved_list.values, host_allocator, &context);
    }

    if (iree_status_is_ok(status)) {
      *out_context = context;
      *out_device_list = device_list;
      *out_replay_recorder = replay_recorder;
    } else {
      iree_vm_context_release(context);
      if (replay_recorder) {
        status = iree_status_join(
            status, iree_status_annotate_f(
                        iree_hal_replay_recorder_close(replay_recorder),
                        "closing HAL replay capture"));
        iree_hal_replay_recorder_release(replay_recorder);
      }
      iree_hal_device_list_free(device_list);
    }
  }

  iree_tooling_module_list_reset(&resolved_list);
  iree_vm_module_release(params_module);

  IREE_TRACE_ZONE_END(z0);
  return status;
}

//===----------------------------------------------------------------------===//
// Call steps function
//===----------------------------------------------------------------------===//

static iree_status_t iree_encode_call_steps(iree_vm_context_t* context,
                                            iree_encode_target_t* target,
                                            iree_allocator_t host_allocator,
                                            iree_vm_list_t** out_steps_list) {
  IREE_TRACE_ZONE_BEGIN(z0);

  *out_steps_list = NULL;
  if (!target->steps_fn.module) {
    IREE_TRACE_ZONE_END(z0);
    return iree_ok_status();  // Steps function is optional.
  }

  iree_vm_list_t* outputs = NULL;
  iree_status_t status = iree_vm_list_create(iree_vm_make_undefined_type_def(),
                                             1, host_allocator, &outputs);
  if (iree_status_is_ok(status)) {
    status = iree_vm_invoke(
        context, target->steps_fn, IREE_VM_INVOCATION_FLAG_NONE,
        /*policy=*/NULL, /*inputs=*/NULL, outputs, host_allocator);
  }

  if (iree_status_is_ok(status)) {
    iree_vm_ref_t list_ref = iree_vm_ref_null();
    status = iree_vm_list_get_ref_assign(outputs, 0, &list_ref);
    if (iree_status_is_ok(status)) {
      *out_steps_list = iree_vm_list_deref(list_ref);
      if (*out_steps_list) {
        iree_vm_list_retain(*out_steps_list);
      }
    }
  }

  iree_vm_list_release(outputs);
  IREE_TRACE_ZONE_END(z0);
  return status;
}

//===----------------------------------------------------------------------===//
// Execute encoder
//===----------------------------------------------------------------------===//

static iree_status_t iree_encode_execute(iree_vm_context_t* context,
                                         iree_hal_device_t* device,
                                         iree_encode_target_t* target,
                                         iree_vm_list_t* steps_list,
                                         iree_allocator_t host_allocator) {
  IREE_TRACE_ZONE_BEGIN(z0);

  // Build inputs: [steps_list, wait_fence, signal_fence].
  iree_vm_list_t* inputs = NULL;
  iree_status_t status = iree_vm_list_create(iree_vm_make_undefined_type_def(),
                                             3, host_allocator, &inputs);

  // Push steps list (may be NULL).
  if (iree_status_is_ok(status)) {
    if (steps_list) {
      iree_vm_ref_t steps_ref = iree_vm_list_retain_ref(steps_list);
      status = iree_vm_list_push_ref_move(inputs, &steps_ref);
    } else {
      iree_vm_ref_t null_ref = iree_vm_ref_null();
      status = iree_vm_list_push_ref_move(inputs, &null_ref);
    }
  }

  // Append async fences.
  iree_hal_fence_t* signal_fence = NULL;
  if (iree_status_is_ok(status)) {
    status =
        iree_tooling_append_async_fences(inputs, target->encode_fn, device,
                                         /*wait_fence=*/NULL, &signal_fence);
  }

  // Invoke encoder.
  if (iree_status_is_ok(status)) {
    status = iree_vm_invoke(
        context, target->encode_fn, IREE_VM_INVOCATION_FLAG_NONE,
        /*policy=*/NULL, inputs, /*outputs=*/NULL, host_allocator);
  }

  iree_vm_list_release(inputs);

  // Wait for completion.
  if (iree_status_is_ok(status) && signal_fence) {
    status = iree_hal_fence_wait(signal_fence, iree_infinite_timeout(),
                                 IREE_ASYNC_WAIT_FLAG_NONE);
  }

  iree_hal_fence_release(signal_fence);
  IREE_TRACE_ZONE_END(z0);
  return status;
}

//===----------------------------------------------------------------------===//
// Dump output parameters
//===----------------------------------------------------------------------===//

// Dumps the contents of output archives similar to iree-dump-parameters.
static iree_status_t iree_encode_dump_outputs(iree_output_archive_t* archives,
                                              iree_host_size_t archive_count,
                                              iree_allocator_t host_allocator) {
  IREE_TRACE_ZONE_BEGIN(z0);

  iree_string_builder_t sb;
  iree_string_builder_initialize(host_allocator, &sb);

  iree_status_t status = iree_ok_status();
  for (iree_host_size_t i = 0; i < archive_count && iree_status_is_ok(status);
       ++i) {
    iree_output_archive_t* archive = &archives[i];
    if (!archive->index) continue;

    status = iree_string_builder_append_cstring(
        &sb,
        "//"
        "===-----------------------------------------------------------------"
        "---------------------------------------------===//\n");
    if (!iree_status_is_ok(status)) break;

    // Print archive header.
    iree_io_physical_size_t archive_size =
        iree_io_parameter_archive_builder_total_size(&archive->builder);
    status = iree_string_builder_append_format(
        &sb, "// Output: %.*s (%" PRIu64 " bytes)\n", (int)archive->path.size,
        archive->path.data, archive_size);
    if (!iree_status_is_ok(status)) break;

    // Dump parameter index.
    status = iree_io_parameter_index_dump(archive->scope, archive->index, &sb);
  }

  if (iree_status_is_ok(status)) {
    fprintf(stdout, "%.*s", (int)iree_string_builder_size(&sb),
            iree_string_builder_buffer(&sb));
  }

  iree_string_builder_deinitialize(&sb);
  IREE_TRACE_ZONE_END(z0);
  return status;
}

//===----------------------------------------------------------------------===//
// Main encoding workflow
//===----------------------------------------------------------------------===//

static iree_status_t iree_tooling_encode_parameters(
    iree_allocator_t host_allocator) {
  IREE_TRACE_ZONE_BEGIN(z0);
  iree_status_t status = iree_ok_status();

  // Create VM instance.
  iree_vm_instance_t* instance = NULL;
  IREE_RETURN_AND_END_ZONE_IF_ERROR(
      z0, iree_tooling_create_instance(host_allocator, &instance));

  // Load modules and discover encoder functions.
  iree_tooling_module_list_t module_list;
  iree_vm_module_t* encoder_module = NULL;
  iree_encode_target_set_t target_set;
  status = iree_encode_load_and_discover(instance, host_allocator, &module_list,
                                         &encoder_module, &target_set);

  // Select target.
  iree_encode_target_t* selected_target = NULL;
  if (iree_status_is_ok(status)) {
    status = iree_encode_select_target(&target_set, &selected_target);
  }
  if (iree_status_is_ok(status)) {
    status = iree_encode_validate_target(selected_target);
  }

  // Handle --list_targets (early exit).
  if (iree_status_is_ok(status) && FLAG_list_targets) {
    status = iree_encode_print_targets(encoder_module, &target_set);
    iree_encode_target_set_deinitialize(&target_set);
    iree_tooling_module_list_reset(&module_list);
    iree_vm_instance_release(instance);
    IREE_TRACE_ZONE_END(z0);
    return status;
  }

  // Call indices function.
  iree_vm_list_t* indices_list = NULL;
  if (iree_status_is_ok(status)) {
    status = iree_encode_call_indices(instance, &module_list, selected_target,
                                      host_allocator, &indices_list);
  }

  // Handle --list_parameters (early exit).
  if (iree_status_is_ok(status) && FLAG_list_parameters) {
    status = iree_encode_print_parameters(indices_list);
    iree_vm_list_release(indices_list);
    iree_encode_target_set_deinitialize(&target_set);
    iree_tooling_module_list_reset(&module_list);
    iree_vm_instance_release(instance);
    IREE_TRACE_ZONE_END(z0);
    return status;
  }

  // Parse output flags.
  iree_output_scope_list_t output_list;
  iree_output_scope_list_initialize(host_allocator, &output_list);
  if (iree_status_is_ok(status)) {
    status = iree_encode_parse_output_flags(&output_list);
  }
  if (iree_status_is_ok(status) && output_list.count == 0) {
    status = iree_make_status(
        IREE_STATUS_INVALID_ARGUMENT,
        "no output specified; use --output=[scope=]path.irpa "
        "(e.g., --output=encoded=output.irpa or --output=output.irpa)");
  }

  // Create output archives.
  iree_output_archive_t* archives = NULL;
  if (iree_status_is_ok(status)) {
    status = iree_encode_create_archives(indices_list, &output_list,
                                         host_allocator, &archives);
  }

  // Create encoding context with output providers.
  iree_vm_context_t* context = NULL;
  iree_hal_device_list_t* device_list = NULL;
  iree_hal_replay_recorder_t* replay_recorder = NULL;
  if (iree_status_is_ok(status)) {
    status = iree_encode_create_encoding_context(
        instance, &module_list, archives, output_list.count, host_allocator,
        &context, &device_list, &replay_recorder);
  }
  iree_hal_device_t* device =
      device_list ? iree_hal_device_list_at(device_list, 0) : NULL;

  // Call steps function.
  iree_vm_list_t* steps_list = NULL;
  if (iree_status_is_ok(status)) {
    status = iree_encode_call_steps(context, selected_target, host_allocator,
                                    &steps_list);
  }

  // Execute encoder.
  if (iree_status_is_ok(status)) {
    status = iree_encode_execute(context, device, selected_target, steps_list,
                                 host_allocator);
  }

  // Dump output parameters (unless quiet mode).
  if (iree_status_is_ok(status) && !FLAG_quiet) {
    status =
        iree_encode_dump_outputs(archives, output_list.count, host_allocator);
  }

  // Cleanup.
  iree_vm_list_release(steps_list);
  iree_vm_list_release(indices_list);
  if (archives) {
    for (iree_host_size_t i = 0; i < output_list.count; ++i) {
      iree_output_archive_deinitialize(&archives[i]);
    }
    iree_allocator_free(host_allocator, archives);
  }
  iree_vm_context_release(context);
  if (replay_recorder) {
    status = iree_status_join(
        status,
        iree_status_annotate_f(iree_hal_replay_recorder_close(replay_recorder),
                               "closing HAL replay capture"));
    iree_hal_replay_recorder_release(replay_recorder);
  }
  iree_hal_device_list_free(device_list);
  iree_output_scope_list_deinitialize(&output_list);
  iree_encode_target_set_deinitialize(&target_set);
  iree_tooling_module_list_reset(&module_list);
  iree_vm_instance_release(instance);

  IREE_TRACE_ZONE_END(z0);
  return status;
}

//===----------------------------------------------------------------------===//
// Entry point
//===----------------------------------------------------------------------===//

int main(int argc, char** argv) {
  IREE_TRACE_APP_ENTER();
  IREE_TRACE_ZONE_BEGIN(z0);

  iree_allocator_t host_allocator = iree_allocator_system();
  int exit_code = EXIT_SUCCESS;

  iree_flags_set_usage(
      "iree-encode-parameters",
      "Encodes parameter files using an encoding module.\n"
      "\n"
      "This tool transforms model parameters using an encoder module produced\n"
      "by iree-compile with --iree-parameter-encoder-output-file. The encoder\n"
      "pre-computes parameter transformations (packing, encoding, dispatches)\n"
      "that would otherwise run at model load time.\n"
      "\n"
      "WORKFLOW:\n"
      "  1. Compile main module with encoder output:\n"
      "       iree-compile model.mlir \\\n"
      "         --iree-parameter-encoder-output-file=encoder.mlir \\\n"
      "         --iree-parameter-splat-path=input.irpa \\\n"
      "         -o main.vmfb\n"
      "\n"
      "  2. Compile the encoder module:\n"
      "       iree-compile encoder.mlir -o encoder.vmfb\n"
      "\n"
      "  3. Run the encoder to transform parameters:\n"
      "       iree-encode-parameters \\\n"
      "         --module=encoder.vmfb \\\n"
      "         --parameters=model=input.irpa \\\n"
      "         --output=encoded=output.irpa\n"
      "\n"
      "  4. Run the main module with encoded parameters:\n"
      "       iree-run-module \\\n"
      "         --module=main.vmfb \\\n"
      "         --parameters=model=input.irpa \\\n"
      "         --parameters=encoded=output.irpa\n"
      "\n"
      "FLAGS:\n"
      "  --module=path.vmfb     Encoder module (required)\n"
      "  --parameters=scope=path  Input parameter file(s)\n"
      "  --output=scope=path.irpa  Output encoded parameter file(s)\n"
      "  --list-targets         List available encoding targets\n"
      "  --list-parameters      List parameters that will be encoded\n"
      "  --target=name          Select specific target (default: auto-detect)\n"
      "  --quiet                Suppress output except errors\n");
  iree_flags_parse_checked(IREE_FLAGS_PARSE_MODE_DEFAULT, &argc, &argv);

  if (argc > 1) {
    fprintf(stderr, "Error: no positional arguments expected.\n");
    fprintf(stderr,
            "Use one or more --parameters=file.ext flags to specify parameter "
            "files.\n");
    IREE_TRACE_ZONE_END(z0);
    IREE_TRACE_APP_EXIT(exit_code);
    return EXIT_FAILURE;
  }

  iree_status_t status = iree_tooling_encode_parameters(host_allocator);

  fflush(stdout);
  if (!iree_status_is_ok(status)) {
    iree_status_fprint(stderr, status);
    iree_status_free(status);
    exit_code = EXIT_FAILURE;
  }
  fflush(stderr);

  IREE_TRACE_ZONE_END(z0);
  IREE_TRACE_APP_EXIT(exit_code);
  return exit_code;
}
