// Copyright 2026 International Digital Economy Academy
//
// 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.

///|
fn build_wgsl_ir_writer_final_name_plan(
  view : WgslIrWriterModule,
  shader_module : Module,
) -> WgslIrFinalNamePlan {
  let table = WgslIrFinalNamePlan::empty()
  let namer = WgslIrWriterNamer::WgslIrWriterNamer()
  for slot in view.type_slots() {
    view.allocate_type_name(table, namer, slot)
  }
  for slot in view.entry_point_slots() {
    view.allocate_entry_point_signature_names(table, namer, namer, slot)
    view.reserve_entry_point_var_local_names(table, namer, slot)
  }
  for slot in view.function_slots() {
    view.allocate_function_signature_names(table, namer, namer, slot)
    view.reserve_function_var_local_names(table, namer, slot)
  }
  for slot in view.global_variable_slots() {
    table.names.set(
      wgsl_ir_emit_name_key("global", slot.source_index),
      namer.call_or(slot.item.name, "global"),
    )
  }
  for slot in view.constant_slots() {
    table.names.set(
      wgsl_ir_emit_name_key("const", slot.source_index),
      namer.call_or(slot.item.name, "const"),
    )
  }
  for slot in view.override_slots() {
    table.names.set(
      wgsl_ir_emit_name_key("override", slot.source_index),
      namer.call_or(slot.item.name, "override"),
    )
  }
  for slot in view.function_slots() {
    view.allocate_function_body_names(table, namer, slot, shader_module)
  }
  for slot in view.entry_point_slots() {
    view.allocate_entry_point_body_names(table, namer, slot, shader_module)
  }
  table
}

///|
fn WgslIrWriterModule::allocate_type_name(
  self : WgslIrWriterModule,
  table : WgslIrFinalNamePlan,
  namer : WgslIrWriterNamer,
  slot : WgslIrWriterTypeSlot,
) -> Unit {
  ignore(self)
  let ty = slot.item
  let raw = match ty.name {
    Some(name) => name
    None => "type"
  }
  table.names.set(
    wgsl_ir_emit_name_key("type", slot.source_index),
    namer.call(raw),
  )
  match ty.inner {
    Struct(members, _) | PredeclaredStruct(members, _) => {
      let member_namer = WgslIrWriterNamer::WgslIrWriterNamer()
      for member_index in 0.. name
          None => "member"
        }
        let raw = if self.type_name_is_imported_generated_symbol(ty.name) {
          raw
        } else {
          self.root_struct_member_import_spelling_name(raw)
        }
        table.names.set(
          wgsl_ir_emit_name_key2("member", slot.source_index, member_index),
          member_namer.member_call(raw),
        )
      }
    }
    _ => ()
  }
}

///|
fn WgslIrWriterModule::type_name_is_imported_generated_symbol(
  self : WgslIrWriterModule,
  name : String?,
) -> Bool {
  ignore(self)
  ignore(name)
  false
}

///|
fn WgslIrWriterModule::root_struct_member_import_spelling_name(
  self : WgslIrWriterModule,
  source_name : String,
) -> String {
  if !self.root_struct_member_import_spelling {
    return source_name
  }
  source_name
}

///|
fn WgslIrWriterModule::allocate_entry_point_signature_names(
  self : WgslIrWriterModule,
  table : WgslIrFinalNamePlan,
  module_namer : WgslIrWriterNamer,
  local_namer : WgslIrWriterNamer,
  slot : WgslIrWriterEntryPointSlot,
) -> Unit {
  ignore(self)
  let ep = slot.item
  table.names.set(
    wgsl_ir_emit_name_key("ep", slot.source_index),
    module_namer.call(ep.name),
  )
  for arg_index in 0.. Unit {
  ignore(self)
  let function = slot.item
  table.names.set(
    wgsl_ir_emit_name_key("fn", slot.source_index),
    module_namer.call_or(function.name, "function"),
  )
  for arg_index in 0.. Unit {
  ignore(self)
  let ep = slot.item
  table.allocate_function_body_names_from_arena(
    shader_module,
    EntryPointFunction(slot.source_index),
    ep.function,
    slot.function_plan,
    namer,
  )
}

///|
fn WgslIrWriterModule::reserve_entry_point_var_local_names(
  self : WgslIrWriterModule,
  table : WgslIrFinalNamePlan,
  namer : WgslIrWriterNamer,
  slot : WgslIrWriterEntryPointSlot,
) -> Unit {
  ignore(self)
  table.reserve_function_var_local_names_from_arena(
    EntryPointFunction(slot.source_index),
    slot.item.function,
    slot.function_plan,
    namer,
  )
}

///|
fn WgslIrWriterModule::allocate_function_body_names(
  self : WgslIrWriterModule,
  table : WgslIrFinalNamePlan,
  namer : WgslIrWriterNamer,
  slot : WgslIrWriterFunctionSlot,
  shader_module : Module,
) -> Unit {
  ignore(self)
  let function = slot.item
  table.allocate_function_body_names_from_arena(
    shader_module,
    UserFunction(slot.source_index),
    function,
    slot.function_plan,
    namer,
  )
}

///|
fn WgslIrWriterModule::reserve_function_var_local_names(
  self : WgslIrWriterModule,
  table : WgslIrFinalNamePlan,
  namer : WgslIrWriterNamer,
  slot : WgslIrWriterFunctionSlot,
) -> Unit {
  ignore(self)
  table.reserve_function_var_local_names_from_arena(
    UserFunction(slot.source_index),
    slot.item,
    slot.function_plan,
    namer,
  )
}