/// Synor Compiler SDK Examples for Flutter/Dart
///
/// Demonstrates smart contract compilation and analysis:
/// - WASM contract compilation and optimization
/// - ABI extraction and encoding
/// - Contract analysis and security scanning
/// - Validation and verification
library;

import 'dart:io';
import 'dart:typed_data';
import 'package:synor_compiler/synor_compiler.dart';

Future<void> main() async {
  // Initialize client
  final config = CompilerConfig(
    apiKey: Platform.environment['SYNOR_API_KEY'] ?? 'your-api-key',
    endpoint: 'https://compiler.synor.io/v1',
    timeout: const Duration(seconds: 60),
    retries: 3,
    debug: false,
    defaultOptimizationLevel: OptimizationLevel.size,
    maxContractSize: 256 * 1024,
    useWasmOpt: true,
    validate: true,
    extractMetadata: true,
    generateAbi: true,
  );

  final compiler = SynorCompiler(config);

  try {
    // Check service health
    final healthy = await compiler.healthCheck();
    print('Service healthy: $healthy\n');

    // Run examples
    await compileContractExample(compiler);
    await compilationModesExample(compiler);
    await abiExample(compiler);
    await analysisExample(compiler);
    await validationExample(compiler);
    await securityExample(compiler);
  } finally {
    await compiler.close();
  }
}

/// Create a minimal valid WASM module for testing.
Uint8List createMinimalWasm() {
  return Uint8List.fromList([
    0x00, 0x61, 0x73, 0x6d, // Magic: \0asm
    0x01, 0x00, 0x00, 0x00, // Version: 1
    // Type section
    0x01, 0x07, 0x01, 0x60, 0x02, 0x7f, 0x7f, 0x01, 0x7f,
    // Function section
    0x03, 0x02, 0x01, 0x00,
    // Export section
    0x07, 0x08, 0x01, 0x04, 0x61, 0x64, 0x64, 0x00, 0x00,
    // Code section
    0x0a, 0x09, 0x01, 0x07, 0x00, 0x20, 0x00, 0x20, 0x01, 0x6a, 0x0b,
  ]);
}

Future<void> compileContractExample(SynorCompiler compiler) async {
  print('=== Contract Compilation ===');

  final wasm = createMinimalWasm();

  final result = await compiler.compile(
    wasm,
    options: CompileOptions(
      optimizationLevel: OptimizationLevel.size,
      useWasmOpt: true,
      validate: true,
      extractMetadata: true,
      generateAbi: true,
      stripOptions: StripOptions(
        stripDebug: true,
        stripProducers: true,
        stripNames: true,
        stripCustom: true,
        stripUnused: true,
        preserveSections: [],
      ),
    ),
  );

  print('Compilation result:');
  print('  Contract ID: ${result.contractId}');
  print('  Code hash: ${result.codeHash}');
  print('  Original size: ${result.originalSize} bytes');
  print('  Optimized size: ${result.optimizedSize} bytes');
  print('  Size reduction: ${result.sizeReduction.toStringAsFixed(1)}%');
  print('  Estimated deploy gas: ${result.estimatedDeployGas}');

  if (result.metadata != null) {
    print('\nMetadata:');
    print('  Name: ${result.metadata!.name}');
    print('  Version: ${result.metadata!.version}');
    print('  SDK Version: ${result.metadata!.sdkVersion}');
  }

  if (result.abi != null) {
    print('\nABI:');
    print('  Functions: ${result.abi!.functions?.length ?? 0}');
    print('  Events: ${result.abi!.events?.length ?? 0}');
    print('  Errors: ${result.abi!.errors?.length ?? 0}');
  }

  print('');
}

Future<void> compilationModesExample(SynorCompiler compiler) async {
  print('=== Compilation Modes ===');

  final wasm = createMinimalWasm();

  // Development mode: fast compilation, debugging support
  print('Development mode:');
  final devResult = await compiler.contracts.compileDev(wasm);
  print('  Size: ${devResult.optimizedSize} bytes');
  print('  Optimization: none');

  // Production mode: maximum optimization
  print('\nProduction mode:');
  final prodResult = await compiler.contracts.compileProduction(wasm);
  print('  Size: ${prodResult.optimizedSize} bytes');
  print('  Optimization: aggressive');
  print('  Size savings: ${devResult.optimizedSize - prodResult.optimizedSize} bytes');

  // Custom optimization levels
  print('\nOptimization levels:');
  final levels = [
    OptimizationLevel.none,
    OptimizationLevel.basic,
    OptimizationLevel.size,
    OptimizationLevel.aggressive,
  ];

  for (final level in levels) {
    final result = await compiler.compile(
      wasm,
      options: CompileOptions(optimizationLevel: level),
    );
    print('  $level: ${result.optimizedSize} bytes');
  }

  print('');
}

Future<void> abiExample(SynorCompiler compiler) async {
  print('=== ABI Operations ===');

  final wasm = createMinimalWasm();

  // Extract ABI from WASM
  final abi = await compiler.abi.extract(wasm);
  print('Contract: ${abi.name}');
  print('Version: ${abi.version}');

  // List functions
  if (abi.functions != null && abi.functions!.isNotEmpty) {
    print('\nFunctions:');
    for (final func in abi.functions!) {
      final inputs = func.inputs
              ?.map((i) => '${i.name}: ${i.type.typeName}')
              .join(', ') ??
          '';
      final outputs = func.outputs?.map((o) => o.type.typeName).join(', ') ?? 'void';
      final modifiers = [
        if (func.view) 'view',
        if (func.payable) 'payable',
      ].join(' ');
      print('  ${func.name}($inputs) -> $outputs $modifiers');
      print('    Selector: ${func.selector}');
    }
  }

  // List events
  if (abi.events != null && abi.events!.isNotEmpty) {
    print('\nEvents:');
    for (final event in abi.events!) {
      final params = event.params
              ?.map((p) =>
                  '${p.indexed ? "indexed " : ""}${p.name}: ${p.type.typeName}')
              .join(', ') ??
          '';
      print('  ${event.name}($params)');
      print('    Topic: ${event.topic}');
    }
  }

  // Encode a function call
  if (abi.functions != null && abi.functions!.isNotEmpty) {
    final func = abi.functions!.first;
    final encoded = await compiler.abi.encodeCall(func, ['arg1', 'arg2']);
    print('\nEncoded call to ${func.name}: $encoded');

    // Decode a result
    final decoded = await compiler.abi.decodeResult(func, encoded);
    print('Decoded result: $decoded');
  }

  print('');
}

Future<void> analysisExample(SynorCompiler compiler) async {
  print('=== Contract Analysis ===');

  final wasm = createMinimalWasm();

  // Full analysis
  final analysis = await compiler.analysis.analyze(wasm);

  // Size breakdown
  if (analysis.sizeBreakdown != null) {
    print('Size breakdown:');
    print('  Code: ${analysis.sizeBreakdown!.code} bytes');
    print('  Data: ${analysis.sizeBreakdown!.data} bytes');
    print('  Functions: ${analysis.sizeBreakdown!.functions} bytes');
    print('  Memory: ${analysis.sizeBreakdown!.memory} bytes');
    print('  Exports: ${analysis.sizeBreakdown!.exports} bytes');
    print('  Imports: ${analysis.sizeBreakdown!.imports} bytes');
    print('  Total: ${analysis.sizeBreakdown!.total} bytes');
  }

  // Function analysis
  if (analysis.functions != null && analysis.functions!.isNotEmpty) {
    print('\nFunction analysis:');
    for (final func in analysis.functions!.take(5)) {
      print('  ${func.name}:');
      print('    Size: ${func.size} bytes');
      print('    Instructions: ${func.instructionCount}');
      print('    Locals: ${func.localCount}');
      print('    Exported: ${func.exported}');
      print('    Estimated gas: ${func.estimatedGas}');
    }
  }

  // Import analysis
  if (analysis.imports != null && analysis.imports!.isNotEmpty) {
    print('\nImports:');
    for (final imp in analysis.imports!) {
      print('  ${imp.module}.${imp.name} (${imp.kind})');
    }
  }

  // Gas analysis
  if (analysis.gasAnalysis != null) {
    print('\nGas analysis:');
    print('  Deployment: ${analysis.gasAnalysis!.deploymentGas}');
    print('  Memory init: ${analysis.gasAnalysis!.memoryInitGas}');
    print('  Data section: ${analysis.gasAnalysis!.dataSectionGas}');
  }

  // Extract metadata
  final metadata = await compiler.analysis.extractMetadata(wasm);
  print('\nContract metadata:');
  print('  Name: ${metadata.name}');
  print('  Version: ${metadata.version}');
  print('  Build timestamp: ${metadata.buildTimestamp}');

  // Estimate deployment gas
  final gas = await compiler.analysis.estimateDeployGas(wasm);
  print('\nEstimated deployment gas: $gas');

  print('');
}

Future<void> validationExample(SynorCompiler compiler) async {
  print('=== Contract Validation ===');

  final wasm = createMinimalWasm();

  // Full validation
  final result = await compiler.validation.validate(wasm);
  print('Valid: ${result.valid}');
  print('Exports: ${result.exportCount}');
  print('Imports: ${result.importCount}');
  print('Functions: ${result.functionCount}');
  print('Memory pages: ${result.memoryPages}');

  if (result.errors != null && result.errors!.isNotEmpty) {
    print('\nValidation errors:');
    for (final error in result.errors!) {
      print('  [${error.code}] ${error.message}');
      if (error.location != null) {
        print('    at ${error.location}');
      }
    }
  }

  if (result.warnings != null && result.warnings!.isNotEmpty) {
    print('\nWarnings:');
    for (final warning in result.warnings!) {
      print('  $warning');
    }
  }

  // Quick validation
  final isValid = await compiler.validation.isValid(wasm);
  print('\nQuick validation: $isValid');

  // Get validation errors only
  final errors = await compiler.validation.getErrors(wasm);
  print('Error count: ${errors.length}');

  // Validate required exports
  final hasRequired = await compiler.validation.validateExports(
    wasm,
    ['init', 'execute', 'query'],
  );
  print('Has required exports: $hasRequired');

  // Validate memory constraints
  final memoryValid = await compiler.validation.validateMemory(wasm, 16);
  print('Memory within 16 pages: $memoryValid');

  print('');
}

Future<void> securityExample(SynorCompiler compiler) async {
  print('=== Security Scanning ===');

  final wasm = createMinimalWasm();

  final security = await compiler.analysis.securityScan(wasm);

  print('Security score: ${security.score}/100');

  if (security.issues != null && security.issues!.isNotEmpty) {
    print('\nSecurity issues:');
    final severityIcons = {
      'critical': '[CRIT]',
      'high': '[HIGH]',
      'medium': '[MED]',
      'low': '[LOW]',
    };
    for (final issue in security.issues!) {
      final icon = severityIcons[issue.severity] ?? '[???]';
      print('$icon [${issue.severity.toUpperCase()}] ${issue.type}');
      print('   ${issue.description}');
      if (issue.location != null) {
        print('   at ${issue.location}');
      }
    }
  } else {
    print('No security issues found!');
  }

  if (security.recommendations != null && security.recommendations!.isNotEmpty) {
    print('\nRecommendations:');
    for (final rec in security.recommendations!) {
      print('  • $rec');
    }
  }

  print('');
}
