<commit_before>require 'dependency_container'
require 'securerandom'
require "specialist_document_repository"
require 'builders/specialist_document_builder'
require 'gds_api/panopticon'
require 'panopticon_registerer'
require "specialist_document_attachment_processor"
require "specialist_document_exporter"
require "rendered_specialist_document"
require "specialist_document_govspeak_to_html_renderer"
require "specialist_document_header_extractor"
require "finder_api_notifier"
require "finder_api"
require "validators/slug_uniqueness_validator"
require "marshallers/document_association_marshaller"
require "manual_link_list_body_renderer"

$LOAD_PATH.unshift(File.expand_path("../..", "app/services"))

SpecialistPublisherWiring = DependencyContainer.new do

  define_factory(:observers) {
    ObserversRegistry.new(
      document_content_api_exporter: get(:specialist_document_content_api_exporter),
      finder_api_notifier: get(:finder_api_notifier),
      document_panopticon_registerer: get(:document_panopticon_registerer),
      manual_panopticon_registerer: get(:manual_panopticon_registerer),
      manual_document_panopticon_registerer: get(:manual_document_panopticon_registerer),
      manual_content_api_exporter: get(:manual_and_documents_content_api_exporter),
    )
  }

  define_factory(:services) {
    ServiceRegistry.new(
      document_builder: get(:specialist_document_builder),
      document_repository: get(:specialist_document_repository),
      creation_listeners: get(:specialist_document_creation_observers),
      withdrawal_listeners: get(:specialist_document_withdrawal_observers),
      document_renderer: get(:specialist_document_renderer),

      manual_repository_factory: get(:manual_repository_factory),
      plain_manual_repository_factory: get(:plain_manual_repository_factory),
      manual_builder: get(:manual_builder),

      observers: get(:observers),
    )
  }

  define_factory(:manual_builder) {
    ->(attrs) {
      default = {
        id: SecureRandom.uuid,
        slug: get(:manual_slug_generator).call(attrs.fetch(:title)),
        summary: "",
        state: "draft",
        organisation_slug: "",
        updated_at: "",
      }

      Manual.new(default.merge(attrs))
    }
  }

  define_instance(:specialist_document_editions) { SpecialistDocumentEdition }
  define_instance(:artefacts) { Artefact }
  define_instance(:panopticon_mappings) { PanopticonMapping }
  define_singleton(:panopticon_api) do
    GdsApi::Panopticon.new(get(:plek).find("panopticon"), PANOPTICON_API_CREDENTIALS)
  end

  define_singleton(:specialist_document_factory) {
    ->(*args) {
      SpecialistDocument.new(
        get(:cma_slug_generator),
        get(:edition_factory),
        *args,
      )
    }
  }


  define_singleton(:specialist_document_repository) do
    SpecialistDocumentRepository.new(
      get(:panopticon_mappings),
      get(:specialist_document_editions).where(document_type: "cma_case"),
      get(:specialist_document_factory),
    )
  end

  define_singleton(:specific_manual_document_repository) do
    ->(manual) {
      specific_manual_document_factory = get(:validated_manual_document_factory_factory).call(manual)

      SpecialistDocumentRepository.new(
        get(:panopticon_mappings),
        get(:specialist_document_editions).where(document_type: "manual"),
        specific_manual_document_factory,
      )
    }
  end

  define_factory(:manual_repository_factory) {
    ->(organisation_slug) {
      get(:plain_manual_repository_factory).call(
        organisation_slug: organisation_slug,
        association_marshallers: [
          DocumentAssociationMarshaller.new(
            document_repository: get(:specific_manual_document_repository),
            decorator: ->(manual, attrs) {
              ManualWithDocuments.new(
                get(:manual_document_builder),
                manual,
                attrs,
              )
            }
          ),
        ],
      )
    }
  }

  define_factory(:plain_manual_repository_factory) {
    ->(dependencies) {
      ManualRepository.new(
        {
          association_marshallers: [],
          factory: Manual.method(:new),
          collection: ManualRecord.find_by_organisation(
            dependencies.fetch(:organisation_slug)
          ),
        }.merge(dependencies.except(:organisation_slug))
      )
    }
  }

  define_singleton(:id_generator) { SecureRandom.method(:uuid) }

  define_singleton(:edition_factory) { SpecialistDocumentEdition.method(:new) }
  define_singleton(:attachment_factory) { Attachment.method(:new) }

  define_factory(:specialist_document_builder) {
    SpecialistDocumentBuilder.new(
      get(:validated_specialist_document_factory),
      get(:id_generator),
    )
  }

  define_factory(:validated_specialist_document_factory) {
    ->(*args) {
      SlugUniquenessValidator.new(
        get(:specialist_document_repository),
        get(:specialist_document_factory).call(*args),
      )
    }
  }

  define_factory(:manual_document_builder) {
    ->(manual, attrs) {
      defaults = {
          document_type: "manual",
          opened_date: Date.parse('1/04/2014'),
          market_sector: 'manual',
          case_type: 'manual',
          case_state: 'manual',
        }

      get(:validated_manual_document_factory_factory)
        .call(manual)
        .call(
          get(:id_generator).call,
          [],
        ).update(attrs.reverse_merge(defaults))
    }
  }

  define_factory(:validated_manual_document_factory_factory) {
    ->(manual) {
      slug_generator = get(:manual_document_slug_generator).call(manual.slug)

      ->(id, editions) {
        SlugUniquenessValidator.new(
          get(:specialist_document_repository),
          SpecialistDocument.new(
            slug_generator,
            get(:edition_factory),
            id,
            editions,
          )
        )
      }
    }
  }

  define_factory(:cma_slug_generator) { SlugGenerator.new(prefix: "cma-cases") }
  define_factory(:manual_slug_generator) { SlugGenerator.new(prefix: "manuals") }
  define_factory(:manual_document_slug_generator) {
    ->(manual_slug) {
      SlugGenerator.new(prefix: manual_slug)
    }
  }

  define_instance(:markdown_renderer) {<commit_msg>Generate manual slugs under /guidance<commit_after>require 'dependency_container'
require 'securerandom'
require "specialist_document_repository"
require 'builders/specialist_document_builder'
require 'gds_api/panopticon'
require 'panopticon_registerer'
require "specialist_document_attachment_processor"
require "specialist_document_exporter"
require "rendered_specialist_document"
require "specialist_document_govspeak_to_html_renderer"
require "specialist_document_header_extractor"
require "finder_api_notifier"
require "finder_api"
require "validators/slug_uniqueness_validator"
require "marshallers/document_association_marshaller"
require "manual_link_list_body_renderer"

$LOAD_PATH.unshift(File.expand_path("../..", "app/services"))

SpecialistPublisherWiring = DependencyContainer.new do

  define_factory(:observers) {
    ObserversRegistry.new(
      document_content_api_exporter: get(:specialist_document_content_api_exporter),
      finder_api_notifier: get(:finder_api_notifier),
      document_panopticon_registerer: get(:document_panopticon_registerer),
      manual_panopticon_registerer: get(:manual_panopticon_registerer),
      manual_document_panopticon_registerer: get(:manual_document_panopticon_registerer),
      manual_content_api_exporter: get(:manual_and_documents_content_api_exporter),
    )
  }

  define_factory(:services) {
    ServiceRegistry.new(
      document_builder: get(:specialist_document_builder),
      document_repository: get(:specialist_document_repository),
      creation_listeners: get(:specialist_document_creation_observers),
      withdrawal_listeners: get(:specialist_document_withdrawal_observers),
      document_renderer: get(:specialist_document_renderer),

      manual_repository_factory: get(:manual_repository_factory),
      plain_manual_repository_factory: get(:plain_manual_repository_factory),
      manual_builder: get(:manual_builder),

      observers: get(:observers),
    )
  }

  define_factory(:manual_builder) {
    ->(attrs) {
      default = {
        id: SecureRandom.uuid,
        slug: get(:manual_slug_generator).call(attrs.fetch(:title)),
        summary: "",
        state: "draft",
        organisation_slug: "",
        updated_at: "",
      }

      Manual.new(default.merge(attrs))
    }
  }

  define_instance(:specialist_document_editions) { SpecialistDocumentEdition }
  define_instance(:artefacts) { Artefact }
  define_instance(:panopticon_mappings) { PanopticonMapping }
  define_singleton(:panopticon_api) do
    GdsApi::Panopticon.new(get(:plek).find("panopticon"), PANOPTICON_API_CREDENTIALS)
  end

  define_singleton(:specialist_document_factory) {
    ->(*args) {
      SpecialistDocument.new(
        get(:cma_slug_generator),
        get(:edition_factory),
        *args,
      )
    }
  }


  define_singleton(:specialist_document_repository) do
    SpecialistDocumentRepository.new(
      get(:panopticon_mappings),
      get(:specialist_document_editions).where(document_type: "cma_case"),
      get(:specialist_document_factory),
    )
  end

  define_singleton(:specific_manual_document_repository) do
    ->(manual) {
      specific_manual_document_factory = get(:validated_manual_document_factory_factory).call(manual)

      SpecialistDocumentRepository.new(
        get(:panopticon_mappings),
        get(:specialist_document_editions).where(document_type: "manual"),
        specific_manual_document_factory,
      )
    }
  end

  define_factory(:manual_repository_factory) {
    ->(organisation_slug) {
      get(:plain_manual_repository_factory).call(
        organisation_slug: organisation_slug,
        association_marshallers: [
          DocumentAssociationMarshaller.new(
            document_repository: get(:specific_manual_document_repository),
            decorator: ->(manual, attrs) {
              ManualWithDocuments.new(
                get(:manual_document_builder),
                manual,
                attrs,
              )
            }
          ),
        ],
      )
    }
  }

  define_factory(:plain_manual_repository_factory) {
    ->(dependencies) {
      ManualRepository.new(
        {
          association_marshallers: [],
          factory: Manual.method(:new),
          collection: ManualRecord.find_by_organisation(
            dependencies.fetch(:organisation_slug)
          ),
        }.merge(dependencies.except(:organisation_slug))
      )
    }
  }

  define_singleton(:id_generator) { SecureRandom.method(:uuid) }

  define_singleton(:edition_factory) { SpecialistDocumentEdition.method(:new) }
  define_singleton(:attachment_factory) { Attachment.method(:new) }

  define_factory(:specialist_document_builder) {
    SpecialistDocumentBuilder.new(
      get(:validated_specialist_document_factory),
      get(:id_generator),
    )
  }

  define_factory(:validated_specialist_document_factory) {
    ->(*args) {
      SlugUniquenessValidator.new(
        get(:specialist_document_repository),
        get(:specialist_document_factory).call(*args),
      )
    }
  }

  define_factory(:manual_document_builder) {
    ->(manual, attrs) {
      defaults = {
          document_type: "manual",
          opened_date: Date.parse('1/04/2014'),
          market_sector: 'manual',
          case_type: 'manual',
          case_state: 'manual',
        }

      get(:validated_manual_document_factory_factory)
        .call(manual)
        .call(
          get(:id_generator).call,
          [],
        ).update(attrs.reverse_merge(defaults))
    }
  }

  define_factory(:validated_manual_document_factory_factory) {
    ->(manual) {
      slug_generator = get(:manual_document_slug_generator).call(manual.slug)

      ->(id, editions) {
        SlugUniquenessValidator.new(
          get(:specialist_document_repository),
          SpecialistDocument.new(
            slug_generator,
            get(:edition_factory),
            id,
            editions,
          )
        )
      }
    }
  }

  define_factory(:cma_slug_generator) { SlugGenerator.new(prefix: "cma-cases") }
  define_factory(:manual_slug_generator) { SlugGenerator.new(prefix: "guidance") }
  define_factory(:manual_document_slug_generator) {
    ->(manual_slug) {
      SlugGenerator.new(prefix: manual_slug)
    }
  }

  define_instance(:markdown_renderer) {
{'fraction_non_alphanumeric': 0.09976872158864343, 'fraction_numerical': 0.0011165164686179122, 'mean_word_length': 3.6513353115727, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 25, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2873251', 'n_tokens_mistral': 3830, 'n_tokens_neox': 3739, 'n_words': 412}