/*
 * Copyright 2014 Google Inc. All rights reserved.
 *
 * 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.
 */

#define IN_FRUIT_CPP_FILE 1

#include <algorithm>
#include <cstdlib>
#include <fruit/impl/util/type_info.h>
#include <iostream>
#include <memory>
#include <vector>

#include <fruit/impl/data_structures/semistatic_graph.templates.h>
#include <fruit/impl/injector/injector_storage.h>
#include <fruit/impl/normalized_component_storage/binding_normalization.h>
#include <fruit/impl/normalized_component_storage/binding_normalization.templates.h>
#include <fruit/impl/normalized_component_storage/normalized_component_storage.h>

using std::cout;
using std::endl;

namespace fruit {
namespace impl {

void BindingNormalization::printLazyComponentInstallationLoop(
    const std::vector<ComponentStorageEntry, ArenaAllocator<ComponentStorageEntry>>& entries_to_process,
    const ComponentStorageEntry& last_entry) {
  std::cerr << "Found a loop while expanding components passed to PartialComponent::install()." << std::endl;
  std::cerr << "Component installation trace (from top-level to the most deeply-nested):" << std::endl;
  for (const ComponentStorageEntry& entry : entries_to_process) {
    switch (entry.kind) {
    case ComponentStorageEntry::Kind::COMPONENT_WITH_ARGS_END_MARKER:
      if (entry.type_id == last_entry.type_id &&
          last_entry.kind == ComponentStorageEntry::Kind::LAZY_COMPONENT_WITH_ARGS &&
          *entry.lazy_component_with_args.component == *last_entry.lazy_component_with_args.component) {
        std::cerr << "<-- The loop starts here" << std::endl;
      }
      std::cerr << std::string(entry.lazy_component_with_args.component->getFunTypeId()) << std::endl;
      break;

    case ComponentStorageEntry::Kind::COMPONENT_WITHOUT_ARGS_END_MARKER:
      if (entry.type_id == last_entry.type_id &&
          last_entry.kind == ComponentStorageEntry::Kind::LAZY_COMPONENT_WITH_NO_ARGS &&
          entry.lazy_component_with_no_args.erased_fun == last_entry.lazy_component_with_no_args.erased_fun) {
        std::cerr << "<-- The loop starts here" << std::endl;
      }
      std::cerr << std::string(entry.type_id) << std::endl;
      break;

    default:
      break;
    }
  }

  switch (last_entry.kind) { // LCOV_EXCL_BR_LINE
  case ComponentStorageEntry::Kind::LAZY_COMPONENT_WITH_ARGS:
    std::cerr << std::string(last_entry.lazy_component_with_args.component->getFunTypeId()) << std::endl;
    break;

  case ComponentStorageEntry::Kind::LAZY_COMPONENT_WITH_NO_ARGS:
    std::cerr << std::string(last_entry.type_id) << std::endl;
    break;

  default:
    FRUIT_UNREACHABLE; // LCOV_EXCL_LINE
  }

  exit(1);
}

void BindingNormalization::printMultipleBindingsError(TypeId type) {
  std::cerr << "Fatal injection error: the type " << type.type_info->name()
            << " was provided more than once, with different bindings." << std::endl
            << "This was not caught at compile time because at least one of the involved components bound this type "
            << "but didn't expose it in the component signature." << std::endl
            << "If the type has a default constructor or an Inject annotation, this problem may arise even if this "
            << "type is bound/provided by only one component (and then hidden), if this type is auto-injected in "
            << "another component." << std::endl
            << "If the source of the problem is unclear, try exposing this type in all the component signatures where "
            << "it's bound; if no component hides it this can't happen." << std::endl;
  exit(1);
}

void BindingNormalization::printIncompatibleComponentReplacementsError(
    const ComponentStorageEntry& replaced_component_entry, const ComponentStorageEntry& replacement_component_entry1,
    const ComponentStorageEntry& replacement_component_entry2) {
  using fun_t = void (*)();

  fun_t replaced_fun_address;
  switch (replaced_component_entry.kind) {
  case ComponentStorageEntry::Kind::REPLACED_LAZY_COMPONENT_WITH_ARGS:
    replaced_fun_address = replaced_component_entry.lazy_component_with_args.component->erased_fun;
    break;

  case ComponentStorageEntry::Kind::REPLACED_LAZY_COMPONENT_WITH_NO_ARGS:
    replaced_fun_address = replaced_component_entry.lazy_component_with_no_args.erased_fun;
    break;

  default:
    FRUIT_UNREACHABLE; // LCOV_EXCL_LINE
  }

  fun_t replacement_fun_address1;
  switch (replacement_component_entry1.kind) {
  case ComponentStorageEntry::Kind::REPLACEMENT_LAZY_COMPONENT_WITH_ARGS:
    replacement_fun_address1 = replacement_component_entry1.lazy_component_with_args.component->erased_fun;
    break;

  case ComponentStorageEntry::Kind::REPLACEMENT_LAZY_COMPONENT_WITH_NO_ARGS:
    replacement_fun_address1 = replacement_component_entry1.lazy_component_with_no_args.erased_fun;
    break;

  default:
    FRUIT_UNREACHABLE; // LCOV_EXCL_LINE
  }

  fun_t replacement_fun_address2;
  switch (replacement_component_entry2.kind) {
  case ComponentStorageEntry::Kind::REPLACEMENT_LAZY_COMPONENT_WITH_ARGS:
    replacement_fun_address2 = replacement_component_entry2.lazy_component_with_args.component->erased_fun;
    break;

  case ComponentStorageEntry::Kind::REPLACEMENT_LAZY_COMPONENT_WITH_NO_ARGS:
    replacement_fun_address2 = replacement_component_entry2.lazy_component_with_no_args.erased_fun;
    break;

  default:
    FRUIT_UNREACHABLE; // LCOV_EXCL_LINE
  }

  constexpr static bool function_pointers_have_same_size = sizeof(void*) == sizeof(fun_t);
  if (function_pointers_have_same_size) {
    std::cerr << "Fatal injection error: the component function at " << reinterpret_cast<void*>(replaced_fun_address)
              << " with signature " << std::string(replaced_component_entry.type_id)
              << " was replaced (using .replace(...).with(...)) with both the component function at "
              << reinterpret_cast<void*>(replacement_fun_address1) << " with signature "
              << std::string(replacement_component_entry1.type_id) << " and the component function at "
              << reinterpret_cast<void*>(replacement_fun_address2) << " with signature "
              << std::string(replacement_component_entry2.type_id) << " ." << std::endl;
  } else {
    std::cerr << "Fatal injection error: a component function with signature "
              << std::string(replaced_component_entry.type_id)
              << " was replaced (using .replace(...).with(...)) with both a component function with signature "
              << std::string(replacement_component_entry1.type_id) << " and another component function with signature "
              << std::string(replacement_component_entry2.type_id) << " ." << std::endl;
  }
  exit(1);
}

void BindingNormalization::printComponentReplacementFailedBecauseTargetAlreadyExpanded(
    const ComponentStorageEntry& replaced_component_entry, const ComponentStorageEntry& replacement_component_entry) {
  using fun_t = void (*)();

  fun_t replaced_fun_address;
  switch (replaced_component_entry.kind) {
  case ComponentStorageEntry::Kind::REPLACED_LAZY_COMPONENT_WITH_ARGS:
    replaced_fun_address = replaced_component_entry.lazy_component_with_args.component->erased_fun;
    break;

  case ComponentStorageEntry::Kind::REPLACED_LAZY_COMPONENT_WITH_NO_ARGS:
    replaced_fun_address = replaced_component_entry.lazy_component_with_no_args.erased_fun;
    break;

  default:
    FRUIT_UNREACHABLE; // LCOV_EXCL_LINE
  }

  fun_t replacement_fun_address1;
  switch (replacement_component_entry.kind) {
  case ComponentStorageEntry::Kind::REPLACEMENT_LAZY_COMPONENT_WITH_ARGS:
    replacement_fun_address1 = replacement_component_entry.lazy_component_with_args.component->erased_fun;
    break;

  case ComponentStorageEntry::Kind::REPLACEMENT_LAZY_COMPONENT_WITH_NO_ARGS:
    replacement_fun_address1 = replacement_component_entry.lazy_component_with_no_args.erased_fun;
    break;

  default:
    FRUIT_UNREACHABLE; // LCOV_EXCL_LINE
  }

  constexpr static bool function_pointers_have_same_size = sizeof(void*) == sizeof(fun_t);
  if (function_pointers_have_same_size) {
    std::cerr << "Fatal injection error: unable to replace (using .replace(...).with(...)) the component function at "
              << reinterpret_cast<void*>(replaced_fun_address) << " with signature "
              << std::string(replaced_component_entry.type_id) << " with the component function at "
              << reinterpret_cast<void*>(replacement_fun_address1) << " with signature "
              << std::string(replacement_component_entry.type_id)
              << " because the former component function was installed before the .replace(...).with(...)." << std::endl
              << "You should change the order of installation of subcomponents so that .replace(...).with(...) is "
              << "processed before the installation of the component to replace.";
  } else {
    std::cerr << "Fatal injection error: unable to replace (using .replace(...).with(...)) a component function with "
              << "signature " << std::string(replaced_component_entry.type_id)
              << " with a component function at with signature " << std::string(replacement_component_entry.type_id)
              << " because the former component function was installed before the .replace(...).with(...)." << std::endl
              << "You should change the order of installation of subcomponents so that .replace(...).with(...) is "
              << "processed before the installation of the component to replace.";
  }
  exit(1);
}

void BindingNormalization::addMultibindings(std::unordered_map<TypeId, NormalizedMultibindingSet>& multibindings,
                                            FixedSizeAllocator::FixedSizeAllocatorData& fixed_size_allocator_data,
                                            const multibindings_vector_t& multibindingsVector) {

#if FRUIT_EXTRA_DEBUG
  std::cout << "InjectorStorage: adding multibindings:" << std::endl;
#endif
  // Now we must merge multiple bindings for the same type.
  for (auto i = multibindingsVector.begin(); i != multibindingsVector.end(); ++i) {
    const ComponentStorageEntry& multibinding_entry = i->first;
    const ComponentStorageEntry& multibinding_vector_creator_entry = i->second;
    FruitAssert(multibinding_entry.kind ==
                    ComponentStorageEntry::Kind::MULTIBINDING_FOR_OBJECT_TO_CONSTRUCT_THAT_NEEDS_NO_ALLOCATION ||
                multibinding_entry.kind ==
                    ComponentStorageEntry::Kind::MULTIBINDING_FOR_OBJECT_TO_CONSTRUCT_THAT_NEEDS_ALLOCATION ||
                multibinding_entry.kind == ComponentStorageEntry::Kind::MULTIBINDING_FOR_CONSTRUCTED_OBJECT);
    FruitAssert(multibinding_vector_creator_entry.kind == ComponentStorageEntry::Kind::MULTIBINDING_VECTOR_CREATOR);
    NormalizedMultibindingSet& b = multibindings[multibinding_entry.type_id];

    // Might be set already, but we need to set it if there was no multibinding for this type.
    b.get_multibindings_vector = multibinding_vector_creator_entry.multibinding_vector_creator.get_multibindings_vector;

    switch (i->first.kind) { // LCOV_EXCL_BR_LINE
    case ComponentStorageEntry::Kind::MULTIBINDING_FOR_CONSTRUCTED_OBJECT: {
      NormalizedMultibinding normalized_multibinding;
      normalized_multibinding.is_constructed = true;
      normalized_multibinding.object = i->first.multibinding_for_constructed_object.object_ptr;
      b.elems.push_back(normalized_multibinding);
    } break;

    case ComponentStorageEntry::Kind::MULTIBINDING_FOR_OBJECT_TO_CONSTRUCT_THAT_NEEDS_NO_ALLOCATION: {
      fixed_size_allocator_data.addExternallyAllocatedType(i->first.type_id);
      NormalizedMultibinding normalized_multibinding;
      normalized_multibinding.is_constructed = false;
      normalized_multibinding.create = i->first.multibinding_for_object_to_construct.create;
      b.elems.push_back(normalized_multibinding);
    } break;

    case ComponentStorageEntry::Kind::MULTIBINDING_FOR_OBJECT_TO_CONSTRUCT_THAT_NEEDS_ALLOCATION: {
      fixed_size_allocator_data.addType(i->first.type_id);
      NormalizedMultibinding normalized_multibinding;
      normalized_multibinding.is_constructed = false;
      normalized_multibinding.create = i->first.multibinding_for_object_to_construct.create;
      b.elems.push_back(normalized_multibinding);
    } break;

    default:
#if FRUIT_EXTRA_DEBUG
      std::cerr << "Unexpected kind: " << (std::size_t)i->first.kind << std::endl;
#endif
      FRUIT_UNREACHABLE; // LCOV_EXCL_LINE
    }
  }
}

void BindingNormalization::normalizeBindingsWithUndoableBindingCompression(
    FixedSizeVector<ComponentStorageEntry>&& toplevel_entries,
    FixedSizeAllocator::FixedSizeAllocatorData& fixed_size_allocator_data, MemoryPool& memory_pool,
    MemoryPool& memory_pool_for_fully_expanded_components_maps, MemoryPool& memory_pool_for_component_replacements_maps,
    const std::vector<TypeId, ArenaAllocator<TypeId>>& exposed_types,
    std::vector<ComponentStorageEntry, ArenaAllocator<ComponentStorageEntry>>& bindings_vector,
    std::unordered_map<TypeId, NormalizedMultibindingSet>& multibindings,
    BindingCompressionInfoMap& bindingCompressionInfoMap,
    LazyComponentWithNoArgsSet& fully_expanded_components_with_no_args,
    LazyComponentWithArgsSet& fully_expanded_components_with_args,
    LazyComponentWithNoArgsReplacementMap& component_with_no_args_replacements,
    LazyComponentWithArgsReplacementMap& component_with_args_replacements) {

  FruitAssert(bindingCompressionInfoMap.empty());

  normalizeBindingsWithBindingCompression(
      std::move(toplevel_entries), fixed_size_allocator_data, memory_pool,
      memory_pool_for_fully_expanded_components_maps, memory_pool_for_component_replacements_maps, exposed_types,
      bindings_vector, multibindings,
      [&bindingCompressionInfoMap](TypeId c_type_id, NormalizedComponentStorage::CompressedBindingUndoInfo undo_info) {
        bindingCompressionInfoMap[c_type_id] = undo_info;
      },
      [&fully_expanded_components_with_no_args, &memory_pool](LazyComponentWithNoArgsSet& fully_expanded_components) {
        fully_expanded_components_with_no_args = std::move(fully_expanded_components);
        fully_expanded_components = NormalizedComponentStorage::createLazyComponentWithNoArgsSet(0, memory_pool);
      },
      [&fully_expanded_components_with_args, &memory_pool](LazyComponentWithArgsSet& fully_expanded_components) {
        fully_expanded_components_with_args = std::move(fully_expanded_components);
        fully_expanded_components = NormalizedComponentStorage::createLazyComponentWithArgsSet(0, memory_pool);
      },
      [&component_with_no_args_replacements, &memory_pool](LazyComponentWithNoArgsReplacementMap& component_replacements) {
        component_with_no_args_replacements = std::move(component_replacements);
        component_replacements = NormalizedComponentStorage::createLazyComponentWithNoArgsReplacementMap(0, memory_pool);
      },
      [&component_with_args_replacements, &memory_pool](LazyComponentWithArgsReplacementMap& component_replacements) {
        component_with_args_replacements = std::move(component_replacements);
        component_replacements = NormalizedComponentStorage::createLazyComponentWithArgsReplacementMap(0, memory_pool);
      });
}

void BindingNormalization::normalizeBindingsWithPermanentBindingCompression(
    FixedSizeVector<ComponentStorageEntry>&& toplevel_entries,
    FixedSizeAllocator::FixedSizeAllocatorData& fixed_size_allocator_data, MemoryPool& memory_pool,
    const std::vector<TypeId, ArenaAllocator<TypeId>>& exposed_types,
    std::vector<ComponentStorageEntry, ArenaAllocator<ComponentStorageEntry>>& bindings_vector,
    std::unordered_map<TypeId, NormalizedMultibindingSet>& multibindings) {
  normalizeBindingsWithBindingCompression(
      std::move(toplevel_entries), fixed_size_allocator_data, memory_pool, memory_pool, memory_pool, exposed_types,
      bindings_vector, multibindings, [](TypeId, NormalizedComponentStorage::CompressedBindingUndoInfo) {},
      [](LazyComponentWithNoArgsSet&) {}, [](LazyComponentWithArgsSet&) {},
      [](LazyComponentWithNoArgsReplacementMap&) {}, [](LazyComponentWithArgsReplacementMap&) {});
}

void BindingNormalization::normalizeBindingsAndAddTo(
    FixedSizeVector<ComponentStorageEntry>&& toplevel_entries, MemoryPool& memory_pool,
    const NormalizedComponentStorage& base_normalized_component,
    FixedSizeAllocator::FixedSizeAllocatorData& fixed_size_allocator_data,
    std::vector<ComponentStorageEntry, ArenaAllocator<ComponentStorageEntry>>& new_bindings_vector,
    std::unordered_map<TypeId, NormalizedMultibindingSet>& multibindings) {

  multibindings = base_normalized_component.multibindings;

  fixed_size_allocator_data = base_normalized_component.fixed_size_allocator_data;

  multibindings_vector_t multibindings_vector =
      multibindings_vector_t(ArenaAllocator<multibindings_vector_elem_t>(memory_pool));

  HashMapWithArenaAllocator<TypeId, ComponentStorageEntry> binding_data_map =
      createHashMapWithArenaAllocator<TypeId, ComponentStorageEntry>(20 /* capacity */, memory_pool);

  using Graph = NormalizedComponentStorage::Graph;

  normalizeBindings(
      std::move(toplevel_entries), fixed_size_allocator_data, memory_pool, memory_pool, memory_pool, binding_data_map,
      [](ComponentStorageEntry) {},
      [&multibindings_vector](ComponentStorageEntry multibinding, ComponentStorageEntry multibinding_vector_creator) {
        multibindings_vector.emplace_back(multibinding, multibinding_vector_creator);
      },
      [&base_normalized_component](TypeId type_id) { return base_normalized_component.bindings.find(type_id); },
      [&base_normalized_component](Graph::const_node_iterator itr) {
        return !(itr == base_normalized_component.bindings.end());
      },
      [](Graph::const_node_iterator itr) { return itr.isTerminal(); },
      [](Graph::const_node_iterator itr) { return itr.getNode().object; },
      [](Graph::const_node_iterator itr) { return itr.getNode().create; },
      [&base_normalized_component](const LazyComponentWithNoArgs& lazy_component) {
        return base_normalized_component.fully_expanded_components_with_no_args.count(lazy_component) != 0;
      },
      [&base_normalized_component](const LazyComponentWithArgs& lazy_component) {
        return base_normalized_component.fully_expanded_components_with_args.count(lazy_component) != 0;
      },
      [](LazyComponentWithNoArgsSet&) {}, [](LazyComponentWithArgsSet&) {},
      [&base_normalized_component](const LazyComponentWithNoArgs& lazy_component) {
        return base_normalized_component.component_with_no_args_replacements.find(lazy_component);
      },
      [&base_normalized_component](const LazyComponentWithArgs& lazy_component) {
        return base_normalized_component.component_with_args_replacements.find(lazy_component);
      },
      [&base_normalized_component](typename LazyComponentWithNoArgsReplacementMap::const_iterator itr) {
        return itr != base_normalized_component.component_with_no_args_replacements.end();
      },
      [&base_normalized_component](typename LazyComponentWithArgsReplacementMap::const_iterator itr) {
        return itr != base_normalized_component.component_with_args_replacements.end();
      },
      [](typename LazyComponentWithNoArgsReplacementMap::const_iterator itr) { return itr->second; },
      [](typename LazyComponentWithArgsReplacementMap::const_iterator itr) { return itr->second; },
      [](LazyComponentWithNoArgsReplacementMap&) {}, [](LazyComponentWithArgsReplacementMap&) {});

  // Copy the normalized bindings into the result vector.
  new_bindings_vector.clear();
  new_bindings_vector.reserve(binding_data_map.size());
  for (auto& p : binding_data_map) {
    new_bindings_vector.push_back(p.second);
  }

  // Determine what binding compressions must be undone.

  HashSetWithArenaAllocator<TypeId> binding_compressions_to_undo =
      createHashSetWithArenaAllocator<TypeId>(20 /* capacity */, memory_pool);
  for (const ComponentStorageEntry& entry : new_bindings_vector) {
    switch (entry.kind) { // LCOV_EXCL_BR_LINE
    case ComponentStorageEntry::Kind::BINDING_FOR_CONSTRUCTED_OBJECT:
      break;

    case ComponentStorageEntry::Kind::BINDING_FOR_OBJECT_TO_CONSTRUCT_THAT_NEEDS_NO_ALLOCATION:
    case ComponentStorageEntry::Kind::BINDING_FOR_OBJECT_TO_CONSTRUCT_THAT_NEEDS_ALLOCATION:
    case ComponentStorageEntry::Kind::BINDING_FOR_OBJECT_TO_CONSTRUCT_WITH_UNKNOWN_ALLOCATION: {
      const BindingDeps* entry_deps = entry.binding_for_object_to_construct.deps;
      for (std::size_t i = 0; i < entry_deps->num_deps; ++i) {
        auto binding_compression_itr = base_normalized_component.binding_compression_info_map.find(entry_deps->deps[i]);
        if (binding_compression_itr != base_normalized_component.binding_compression_info_map.end() &&
            binding_compression_itr->second.i_type_id != entry.type_id) {
          // The binding compression for `p.second.getDeps()->deps[i]' must be undone because something
          // different from binding_compression_itr->iTypeId is now bound to it.
          binding_compressions_to_undo.insert(entry_deps->deps[i]);
        }
      }
    } break;

    default:
#if FRUIT_EXTRA_DEBUG
      std::cerr << "Unexpected kind: " << (std::size_t)entry.kind << std::endl;
#endif
      FRUIT_UNREACHABLE; // LCOV_EXCL_LINE
      break;
    }
  }

  // Step 3: undo any binding compressions that can no longer be applied.
  for (TypeId cTypeId : binding_compressions_to_undo) {
    auto binding_compression_itr = base_normalized_component.binding_compression_info_map.find(cTypeId);
    FruitAssert(binding_compression_itr != base_normalized_component.binding_compression_info_map.end());
    FruitAssert(!(base_normalized_component.bindings.find(binding_compression_itr->second.i_type_id) ==
                  base_normalized_component.bindings.end()));

    ComponentStorageEntry c_binding;
    c_binding.type_id = cTypeId;
    c_binding.kind = ComponentStorageEntry::Kind::BINDING_FOR_OBJECT_TO_CONSTRUCT_WITH_UNKNOWN_ALLOCATION;
    c_binding.binding_for_object_to_construct = binding_compression_itr->second.c_binding;

    ComponentStorageEntry i_binding;
    i_binding.type_id = binding_compression_itr->second.i_type_id;
    i_binding.kind = ComponentStorageEntry::Kind::BINDING_FOR_OBJECT_TO_CONSTRUCT_THAT_NEEDS_NO_ALLOCATION;
    i_binding.binding_for_object_to_construct = binding_compression_itr->second.i_binding;

    new_bindings_vector.push_back(c_binding);
    // This TypeId is already in normalized_component.bindings, we overwrite it here.
    new_bindings_vector.push_back(i_binding);

#if FRUIT_EXTRA_DEBUG
    std::cout << "InjectorStorage: undoing binding compression for: " << binding_compression_itr->second.i_type_id
              << "->" << cTypeId << std::endl;
#endif
  }

  // Step 4: Add multibindings.
  BindingNormalization::addMultibindings(multibindings, fixed_size_allocator_data, multibindings_vector);
}

void BindingNormalization::handlePreexistingLazyComponentWithArgsReplacement(
    ComponentStorageEntry& replaced_component_entry, const ComponentStorageEntry& preexisting_replacement,
    ComponentStorageEntry& new_replacement) {
  switch (new_replacement.kind) { // LCOV_EXCL_BR_LINE
  case ComponentStorageEntry::Kind::REPLACEMENT_LAZY_COMPONENT_WITH_NO_ARGS:
    if (preexisting_replacement.kind != ComponentStorageEntry::Kind::REPLACEMENT_LAZY_COMPONENT_WITH_NO_ARGS ||
        preexisting_replacement.lazy_component_with_no_args.erased_fun !=
            new_replacement.lazy_component_with_no_args.erased_fun) {
      printIncompatibleComponentReplacementsError(replaced_component_entry, new_replacement, preexisting_replacement);
      FRUIT_UNREACHABLE; // LCOV_EXCL_LINE
    }

    // Duplicate but consistent replacement, we'll ignore it.
    replaced_component_entry.lazy_component_with_args.destroy();
    break;

  case ComponentStorageEntry::Kind::REPLACEMENT_LAZY_COMPONENT_WITH_ARGS:
    if (preexisting_replacement.kind != ComponentStorageEntry::Kind::REPLACEMENT_LAZY_COMPONENT_WITH_ARGS ||
        !(*preexisting_replacement.lazy_component_with_args.component ==
          *new_replacement.lazy_component_with_args.component)) {
      printIncompatibleComponentReplacementsError(replaced_component_entry, new_replacement, preexisting_replacement);
      FRUIT_UNREACHABLE; // LCOV_EXCL_LINE
    }

    // Duplicate but consistent replacement, we'll ignore it.
    replaced_component_entry.lazy_component_with_args.destroy();
    new_replacement.lazy_component_with_args.destroy();
    break;

  default:
    FRUIT_UNREACHABLE; // LCOV_EXCL_LINE
  }
}

void BindingNormalization::handlePreexistingLazyComponentWithNoArgsReplacement(
    ComponentStorageEntry& replaced_component_entry, const ComponentStorageEntry& preexisting_replacement,
    ComponentStorageEntry& new_replacement) {
  switch (new_replacement.kind) { // LCOV_EXCL_BR_LINE
  case ComponentStorageEntry::Kind::REPLACEMENT_LAZY_COMPONENT_WITH_NO_ARGS:
    if (preexisting_replacement.kind != ComponentStorageEntry::Kind::REPLACEMENT_LAZY_COMPONENT_WITH_NO_ARGS ||
        preexisting_replacement.lazy_component_with_no_args.erased_fun !=
            new_replacement.lazy_component_with_no_args.erased_fun) {
      printIncompatibleComponentReplacementsError(replaced_component_entry, new_replacement, preexisting_replacement);
      FRUIT_UNREACHABLE; // LCOV_EXCL_LINE
    }

    // Duplicate but consistent replacement, we'll ignore it.
    break;

  case ComponentStorageEntry::Kind::REPLACEMENT_LAZY_COMPONENT_WITH_ARGS:
    if (new_replacement.kind != ComponentStorageEntry::Kind::REPLACEMENT_LAZY_COMPONENT_WITH_ARGS ||
        !(*preexisting_replacement.lazy_component_with_args.component ==
          *new_replacement.lazy_component_with_args.component)) {
      printIncompatibleComponentReplacementsError(replaced_component_entry, new_replacement, preexisting_replacement);
      FRUIT_UNREACHABLE; // LCOV_EXCL_LINE
    }

    // Duplicate but consistent replacement, we'll ignore it.
    new_replacement.lazy_component_with_args.destroy();
    break;

  default:
    FRUIT_UNREACHABLE; // LCOV_EXCL_LINE
  }
}

} // namespace impl
// We need a LCOV_EXCL_BR_LINE below because for some reason gcov/lcov think there's a branch there.
} // namespace fruit LCOV_EXCL_BR_LINE
