# Channel System Configuration Examples

## Overview

The new jPOS-inspired channel system provides flexible ISO8583 message processing with:
- Multiple framing protocols (ASCII, HEX, BCD, Stream)
- Pluggable filter chain for message transformation
- TPDU header support for payment networks  
- Dynamic channel creation and management
- Backward compatibility with existing NetworkManager

## Basic Configuration

### Application Configuration

Add to your `config/config.exs`:

```elixir
config :da_product_app, :channel_networks, %{
  # Mercury POS terminal connection
  mercury_pos: %{
    channel_type: :ascii,
    host: "pos.mercury.com",
    port: 8000,
    packager: :mercury_iso8583,
    filters: [:validation, :logging],
    connection_opts: [
      keepalive: true,
      send_timeout: 15_000
    ],
    channel_opts: %{
      length_header_size: 4,
      max_message_length: 4096
    }
  },
  
  # VISA acquiring network  
  visa_acquiring: %{
    channel_type: :hex,
    host: "visa.processor.com", 
    port: 5001,
    packager: :visa_iso8583,
    use_tpdu: true,
    destination_nii: "0001",
    source_nii: "0002",
    filters: [
      %{type: :header, options: %{
        tpdu_config: %{
          enabled: true,
          format: :visa,
          destination_nii: "0001",
          source_nii: "0002"
        }
      }},
      :validation,
      :logging
    ]
  },
  
  # MasterCard acquiring network
  mastercard_acquiring: %{
    channel_type: :bcd,
    host: "mastercard.processor.com",
    port: 5002, 
    packager: :mastercard_iso8583,
    use_tpdu: true,
    destination_id: "000001",
    source_id: "000002",
    filters: [
      %{type: :header, options: %{
        tpdu_config: %{
          enabled: true,
          format: :mastercard,
          destination_id: "000001", 
          source_id: "000002"
        }
      }},
      :validation,
      :logging
    ]
  },
  
  # Stream-based network (e.g., BASE24)
  base24_network: %{
    channel_type: :stream,
    host: "base24.processor.com",
    port: 5003,
    packager: :base24_iso8583,
    filters: [:validation, :logging],
    channel_opts: %{
      terminator: <<0x1C>>,  # File separator 
      read_timeout: 30_000
    }
  }
}
```

## Usage Examples

### 1. Using ChannelFactory Directly

```elixir
# Create a simple ASCII channel
config = %{
  type: :ascii,
  host: "localhost",
  port: 8000,
  filters: [:validation, :logging]
}

{:ok, channel_pid} = ChannelFactory.create_channel(config)

# Send a message
message = create_iso8583_message()
{:ok, response} = Channel.send(channel_pid, message, 30_000)

# Stop the channel
ChannelFactory.stop_channel(channel_pid)
```

### 2. Using Pre-configured Scenarios

```elixir
# Create Mercury POS channel with custom port
{:ok, channel_pid} = ChannelFactory.create_channel(:mercury_pos, %{port: 8001})

# Create VISA acquiring channel with defaults
{:ok, visa_pid} = ChannelFactory.create_channel(:visa_acquiring)
```

### 3. Using ChannelAdapter (Recommended)

```elixir
# Start the adapter (usually in application supervision tree)
{:ok, adapter_pid} = ChannelAdapter.start_link()

# Send messages using network names (compatible with existing NetworkManager calls)
message = create_iso8583_message()
{:ok, response} = ChannelAdapter.send_message(:mercury_pos, message)

# List active channels
channels = ChannelAdapter.list_channels()

# Get channel information  
{:ok, info} = ChannelAdapter.get_channel_info(:mercury_pos)
```

## Filter Configuration

### Built-in Filters

1. **ValidationFilter** - Validates ISO8583 message structure
2. **LoggingFilter** - Logs messages with PAN masking
3. **HeaderFilter** - Handles TPDU headers

### Custom Filter Example

```elixir
defmodule MyApp.CustomFilter do
  use DaProductApp.MercuryISO8583.Channels.Filters.Filter
  
  @impl true
  def filter_outgoing(message, context) do
    # Transform outgoing message
    {:ok, message}
  end
  
  @impl true  
  def filter_incoming(message, context) do
    # Transform incoming message
    {:ok, message}
  end
  
  @impl true
  def filter_name, do: "CustomFilter"
  
  @impl true
  def filter_priority, do: 150  # Medium priority
end
```

## TPDU Header Configuration

### VISA TPDU Format

```elixir
tpdu_config: %{
  enabled: true,
  format: :visa,
  destination_nii: "0001",  # 4-digit Network International Identifier
  source_nii: "0002",       # Your NII
  base_flags: 0x00          # Additional flags
}
```

### MasterCard TPDU Format

```elixir
tpdu_config: %{
  enabled: true,
  format: :mastercard,
  destination_id: "000001",  # 6-digit destination (first 4 used)
  source_id: "000002",       # 6-digit source (first 4 used)
  routing_indicator: 0x0,    # Routing information
  base_flags: 0x0           # Message reason flags
}
```

### Custom TPDU Format

```elixir
tpdu_config: %{
  enabled: true,
  format: :custom,
  header_length: 8,
  header_template: "{destination}{source}{mti}{stan}",
  header_parser: fn header ->
    # Custom parsing logic
    {:ok, %{destination: "00", source: "01"}}
  end
}
```

## Channel Types

### ASCII Channel
- Length-prefixed with ASCII digits
- Header: 4 ASCII characters representing message length
- Use for: Mercury POS, some regional networks

### HEX Channel  
- Length-prefixed with hexadecimal encoding
- Header: 4 hex characters representing message length
- Use for: VISA networks, some acquiring processors

### BCD Channel
- Length-prefixed with BCD encoding
- Header: 2 bytes BCD representing message length
- Use for: MasterCard networks, legacy systems

### Stream Channel
- Terminator-based message separation
- Uses configurable terminator bytes
- Use for: BASE24, some legacy protocols

## Migration from NetworkManager

### Automatic Migration

The ChannelAdapter provides automatic compatibility:

```elixir
# Old NetworkManager call
{:ok, response} = NetworkManager.send(:mercury_pos, message)

# New call (same interface)
{:ok, response} = ChannelAdapter.send_message(:mercury_pos, message)
```

### Gradual Migration

1. Configure channels in application config
2. Start ChannelAdapter in supervision tree
3. Update network calls to use ChannelAdapter
4. Enable fallback for compatibility during transition
5. Remove old NetworkManager configuration

## Supervision Tree Integration

Add to your application's supervision tree:

```elixir
def start(_type, _args) do
  children = [
    # Existing children...
    
    # Channel system
    {DaProductApp.MercuryISO8583.Channels.ChannelAdapter, []},
    
    # Or with custom config
    {DaProductApp.MercuryISO8583.Channels.ChannelAdapter, [
      network_configs: Application.get_env(:da_product_app, :channel_networks),
      fallback_enabled: true
    ]}
  ]
  
  opts = [strategy: :one_for_one, name: DaProductApp.Supervisor]
  Supervisor.start_link(children, opts)
end
```

## Monitoring and Debugging

### Channel Status

```elixir
# List all channels with status
ChannelAdapter.list_channels()
# => [
#   %{network: :mercury_pos, type: :ascii, status: :active, ...},
#   %{network: :visa_acquiring, type: :hex, status: :active, ...}
# ]

# Get detailed channel information
{:ok, info} = ChannelAdapter.get_channel_info(:mercury_pos)
```

### Logging Configuration

Enable detailed logging in `config/config.exs`:

```elixir
config :logger, level: :debug

# Filter-specific logging
config :logger, :console,
  format: "[$level] $message $metadata\n",
  metadata: [:channel_type, :network, :mti, :stan]
```

### Error Handling

```elixir
case ChannelAdapter.send_message(:mercury_pos, message) do
  {:ok, response} -> 
    # Success
    process_response(response)
  
  {:error, {:validation_failed, reason}} ->
    # Message validation failed
    Logger.error("Invalid message: #{reason}")
  
  {:error, {:tpdu_error, reason}} ->
    # TPDU header issue
    Logger.error("TPDU error: #{reason}")
  
  {:error, :timeout} ->
    # Network timeout
    Logger.error("Network timeout")
  
  {:error, reason} ->
    # Other errors
    Logger.error("Channel error: #{inspect(reason)}")
end
```

## Performance Considerations

### Connection Pooling
- Each channel maintains one persistent TCP connection
- Channels are created on-demand and reused
- Failed channels are automatically recreated

### Filter Performance
- Filters are applied in priority order
- ValidationFilter should run early (high priority)
- LoggingFilter should run late (low priority)
- Custom filters should set appropriate priorities

### Memory Usage
- Each channel is a separate GenServer process
- Message correlation tracking uses minimal memory
- Filter chain processing is stateless

### Throughput Optimization
- Use appropriate channel type for your network
- Configure connection options for your latency requirements
- Consider message batching for high-volume scenarios
- Monitor channel statistics for performance tuning
