"""Integration tests for both positional parameters and flexible ordering features."""
from pathlib import Path

import pytest

from freyja import FreyjaCLI


def integration_function_simple(required_text: str, format_type: str = "json", verbose: bool = False):
  """Integration function with positional and optional parameters.

  :param required_text: Required text parameter (becomes positional)
  :param format_type: Output format type  
  :param verbose: Enable verbose output
  """
  result = f"Processing: {required_text} (format: {format_type})"
  if verbose:
    result += " [VERBOSE]"
  return result


def integration_function_complex(
    input_file: str,
    output_format: str = "json",
    batch_size: int = 100,
    validate: bool = True,
    debug: bool = False
):
  """Complex integration function with multiple parameter types.

  :param input_file: Input file path (becomes positional)
  :param output_format: Output format
  :param batch_size: Processing batch size
  :param validate: Enable validation
  :param debug: Enable debug mode
  """
  result = f"Processing file: {input_file} -> {output_format} (batch: {batch_size})"
  if validate:
    result += " [VALIDATED]"
  if debug:
    result += " [DEBUG]"
  return result


def integration_function_path_types(
    source_path: Path,
    destination: str = "output/",
    create_backup: bool = False
):
  """Integration function with Path types and positional parameters.

  :param source_path: Source file path (becomes positional)
  :param destination: Destination directory
  :param create_backup: Create backup copy
  """
  result = f"Copying {source_path} to {destination}"
  if create_backup:
    result += " (with backup)"
  return result


class IntegrationClassSimple:
  """Simple integration class for testing both features together."""

  def __init__(self, config_file: str = "config.json", log_level: str = "INFO"):
    """Initialize with global configuration."""
    self.config_file = config_file
    self.log_level = log_level

  def process_item(self, item_id: str, priority: str = "medium", urgent: bool = False):
    """Process an item with positional parameter.

    :param item_id: ID of item to process (becomes positional)
    :param priority: Processing priority
    :param urgent: Mark as urgent
    """
    result = f"Processing item {item_id} (priority: {priority}, config: {self.config_file}, log: {self.log_level})"
    if urgent:
      result += " [URGENT]"
    return result

  def batch_process(self, item_count: int = 10, format_type: str = "json"):
    """Batch processing without positional parameters.

    :param item_count: Number of items to process
    :param format_type: Output format
    """
    return f"Batch processing {item_count} items as {format_type} (config: {self.config_file})"


class IntegrationClassHierarchical:
  """Hierarchical integration class for complex testing scenarios."""

  def __init__(self, base_config: str = "base.json", environment: str = "development"):
    """Initialize with global settings."""
    self.base_config = base_config
    self.environment = environment

  class DataProcessing:
    """Data processing operations with sub-global settings."""

    def __init__(self, workspace: str = "./data", parallel: bool = True):
      """Initialize data processing."""
      self.workspace = workspace
      self.parallel = parallel

    def transform_data(self, dataset_name: str, output_format: str = "parquet", chunk_size: int = 1000):
      """Transform dataset with positional parameter.

      :param dataset_name: Name of dataset to transform (becomes positional)
      :param output_format: Output format
      :param chunk_size: Processing chunk size
      """
      parallel_info = "parallel" if self.parallel else "sequential"
      return f"Transforming dataset '{dataset_name}' -> {output_format} (chunks: {chunk_size}, mode: {parallel_info}, workspace: {self.workspace})"

    def validate_schema(self, schema_file: str, strict: bool = True):
      """Validate schema with positional parameter.

      :param schema_file: Schema file to validate (becomes positional)
      :param strict: Use strict validation
      """
      mode = "strict" if strict else "lenient"
      return f"Validating schema: {schema_file} ({mode} mode, workspace: {self.workspace})"

  class FileOperations:
    """File operations with different sub-global settings."""

    def __init__(self, temp_dir: str = "/tmp", compression: bool = False):
      """Initialize file operations."""
      self.temp_dir = temp_dir
      self.compression = compression

    def merge_files(self, output_filename: str, input_pattern: str = "*.csv", preserve_headers: bool = True):
      """Merge files with positional parameter.

      :param output_filename: Output file name (becomes positional)
      :param input_pattern: Input file pattern
      :param preserve_headers: Preserve CSV headers
      """
      compression_info = "with compression" if self.compression else "without compression"
      headers_info = "preserving headers" if preserve_headers else "no headers"
      return f"Merging {input_pattern} -> {output_filename} ({headers_info}, {compression_info}, temp: {self.temp_dir})"



class TestClassBasedIntegration:
  """Test integration with class-based CLIs."""

  def test_class_positional_with_flexible_global_options(self):
    """Test class CLI with positional parameters and flexible global options."""
    cli = FreyjaCLI(IntegrationClassSimple, "Class Integration CLI")

    # Positional parameter with global options in various positions
    result = cli.run([
      'process-item',
      'ITEM-123',                     # positional parameter
      '--log-level', 'DEBUG',         # global option after positional
      '--priority', 'high',           # command option
      '--config-file', 'prod.json'    # global option at end
    ])
    assert "Processing item ITEM-123" in result
    assert "priority: high" in result
    assert "config: prod.json" in result
    assert "log: DEBUG" in result

  def test_class_mixed_methods_with_flexible_ordering(self):
    """Test class with both positional and non-positional methods with flexible ordering."""
    cli = FreyjaCLI(IntegrationClassSimple, "Mixed Methods CLI")

    # Method with positional parameter
    result1 = cli.run([
      'process-item',
      'ITEM-456',
      '--config-file', 'test.json',   # global option mixed in
      '--urgent'                      # command boolean flag
    ])
    assert "Processing item ITEM-456" in result1
    assert "config: test.json" in result1
    assert "[URGENT]" in result1

    # Method without positional parameters
    result2 = cli.run([
      'batch-process',
      '--log-level', 'WARN',          # global option
      '--item-count', '50',           # command option
      '--format-type', 'xml'          # command option
    ])
    assert "Batch processing 50 items as xml" in result2





class TestIntegrationErrorHandling:
  """Test error handling with both integration features."""


  def test_unknown_options_with_positional_parameters(self):
    """Test unknown option errors with positional parameters."""
    cli = FreyjaCLI(IntegrationClassSimple, "Error Test CLI")

    # Unknown option should cause error regardless of positional parameter
    with pytest.raises(SystemExit):
      cli.run([
        'process-item',
        'ITEM-789',                     # valid positional parameter
        '--unknown-option', 'value'     # invalid option
      ])



class TestIntegrationPerformance:
  """Test performance aspects of integration features."""


  def test_minimal_command_integration(self):
    """Test minimal commands still work with integration features."""
    cli = FreyjaCLI(IntegrationClassSimple, "Minimal Test CLI")

    # Minimal command should work
    result = cli.run(['batch-process'])
    assert "Batch processing 10 items as json" in result
    assert "config: config.json" in result  # default values


class TestIntegrationBackwardCompatibility:
  """Test backward compatibility with existing CLI patterns."""


  def test_help_system_with_integration_features(self):
    """Test that help system works correctly with integration features."""
    cli = FreyjaCLI(IntegrationClassHierarchical, "Help Test CLI")
    parser = cli.create_parser()

    # Help should work normally
    help_text = parser.format_help()
    assert "Help Test CLI" in help_text
    assert "data-processing" in help_text
    assert "file-operations" in help_text

  def test_completion_system_with_integration_features(self):
    """Test that completion system works with integration features."""
    cli = FreyjaCLI(IntegrationClassSimple, "Completion Test CLI", completion=True)

    # Should create successfully
    assert cli.enable_completion is True

    # Should work with positional parameters and flexible ordering
    result = cli.run([
      'process-item',
      'COMP-123',
      '--config-file', 'completion.json'
    ])
    assert "Processing item COMP-123" in result
    assert "config: completion.json" in result


class TestIntegrationRealWorldScenarios:
  """Test realistic real-world scenarios combining both features."""


  def test_admin_tool_scenario(self):
    """Test realistic system administration tool scenario."""
    cli = FreyjaCLI(IntegrationClassSimple, "Admin Tool CLI")

    # Realistic admin task with mixed option positioning
    result = cli.run([
      'process-item',
      'TICKET-2024-001',                # ticket/item ID (positional)
      '--log-level', 'DEBUG',           # global logging for troubleshooting
      '--config-file', 'admin.conf',    # global config file
      '--priority', 'critical',         # command-specific priority
      '--urgent'                        # command-specific urgency flag
    ])
    assert "Processing item TICKET-2024-001" in result
    assert "priority: critical" in result
    assert "config: admin.conf" in result
    assert "log: DEBUG" in result
    assert "[URGENT]" in result
