# `Lather.Mtom.Builder`
[🔗](https://github.com/awksedgreep/lather/blob/v1.0.49/lib/lather/mtom/builder.ex#L1)

MTOM message builder for constructing multipart SOAP messages.

This module handles the construction of MTOM (Message Transmission Optimization Mechanism)
messages by processing SOAP parameters to extract binary attachments and replacing them
with XOP Include references, then packaging everything into a multipart/related MIME message.

## Process Overview

1. **Detect Attachments**: Scan parameters for `{:attachment, data, type}` tuples
2. **Extract & Convert**: Convert attachment tuples to Attachment structs
3. **Replace with XOP**: Replace attachment data with XOP Include references
4. **Build SOAP**: Create SOAP envelope with XOP includes
5. **Package MIME**: Combine SOAP + attachments into multipart message

## Examples

    # Parameters with attachments
    params = %{
      "document" => {:attachment, pdf_data, "application/pdf"},
      "metadata" => %{"title" => "Report"}
    }

    # Build MTOM message
    {:ok, {content_type, body}} = Builder.build_mtom_message(
      :UploadDocument,
      params,
      [namespace: "http://example.com"]
    )

# `build_mtom_message`

```elixir
@spec build_mtom_message(atom() | String.t(), map(), keyword()) ::
  {:ok, {String.t(), binary()}} | {:error, term()}
```

Builds a complete MTOM message with SOAP envelope and binary attachments.

## Parameters

  * `operation` - SOAP operation name (atom or string)
  * `parameters` - Parameters map potentially containing attachment tuples
  * `options` - SOAP envelope building options

## Options

  * `:namespace` - Target namespace for the operation
  * `:headers` - SOAP headers to include
  * `:version` - SOAP version (`:v1_1` or `:v1_2`)
  * `:boundary` - Custom MIME boundary (auto-generated if not provided)
  * `:enable_mtom` - Force MTOM even without attachments (default: auto-detect)

## Returns

  * `{:ok, {content_type_header, multipart_body}}` - Complete MTOM message
  * `{:error, reason}` - If building fails

## Examples

    # Simple file attachment
    params = %{"file" => {:attachment, file_data, "application/pdf"}}
    {:ok, {content_type, body}} = Builder.build_mtom_message(:Upload, params)

    # Multiple attachments
    params = %{
      "documents" => [
        {:attachment, pdf_data, "application/pdf"},
        {:attachment, excel_data, "application/vnd.ms-excel"}
      ]
    }

    {:ok, {content_type, body}} = Builder.build_mtom_message(
      :UploadMultiple,
      params,
      [namespace: "http://example.com/upload"]
    )

# `estimate_message_size`

```elixir
@spec estimate_message_size(map(), non_neg_integer()) :: non_neg_integer()
```

Estimates the total size of a message including all attachments.

## Parameters

  * `parameters` - Parameters containing potential attachments
  * `base_soap_size` - Estimated size of SOAP envelope (optional)

## Returns

  * Total estimated message size in bytes

# `has_attachments?`

```elixir
@spec has_attachments?(map()) :: boolean()
```

Checks if parameters contain any attachment tuples.

## Parameters

  * `parameters` - Parameters map to check

## Returns

  * `true` if attachments are found, `false` otherwise

## Examples

    Builder.has_attachments?(%{"file" => {:attachment, data, "pdf"}}) # true
    Builder.has_attachments?(%{"name" => "John"}) # false

# `process_parameters`

```elixir
@spec process_parameters(map()) ::
  {:ok, {map(), [Lather.Mtom.Attachment.t()]}} | {:error, term()}
```

Processes parameters to extract attachments and replace with XOP includes.

## Parameters

  * `parameters` - Parameters map potentially containing attachment tuples

## Returns

  * `{:ok, {processed_parameters, attachments_list}}` - Processed data
  * `{:error, reason}` - If processing fails

## Examples

    params = %{"file" => {:attachment, data, "application/pdf"}}
    {:ok, {new_params, [attachment]}} = Builder.process_parameters(params)

    # new_params will contain XOP Include reference instead of binary data
    # attachments will contain the Attachment struct

# `validate_attachments`

```elixir
@spec validate_attachments(map()) :: :ok | {:error, term()}
```

Validates that all attachment tuples in parameters are properly formatted.

## Parameters

  * `parameters` - Parameters to validate

## Returns

  * `:ok` if all attachments are valid
  * `{:error, reason}` if validation fails

---

*Consult [api-reference.md](api-reference.md) for complete listing*
