import 'dart:async';
import 'package:oto/cli/cli.dart';
import 'package:oto/oto/agent/agent_config.dart';
import 'package:oto/oto/agent/edge_registration_client.dart';

abstract class AgentRunner {
  Future<void> run(AgentConfig config);
}

class RegistrationException implements Exception {
  final String message;
  RegistrationException(this.message);

  @override
  String toString() => message;
}

class DefaultAgentRunner implements AgentRunner {
  final EdgeRegistrationClient _client;
  final void Function(String)? _onLog;

  DefaultAgentRunner({
    EdgeRegistrationClient? client,
    void Function(String)? onLog,
  })  : _client = client ?? EdgeRegistrationClient(),
        _onLog = onLog;

  @override
  Future<void> run(AgentConfig config) async {
    _log('Starting registration with OTO Edge at "${config.edge.url}"...');

    try {
      final result = await _client.register(config);

      if (!result.accepted) {
        throw RegistrationException(result.rejectReason ??
            'Registration was rejected by the Edge server.');
      }

      _log('Registration successful!');
      _log('Node ID: ${result.nodeId}');
      if (result.alias != null) {
        _log('Alias: ${result.alias}');
      }
    } on RegistrationException {
      rethrow;
    } catch (e) {
      throw RegistrationException('Connection failed: $e');
    }
  }

  void _log(String message) {
    if (_onLog != null) {
      _onLog(message);
    } else {
      CLI.println(message, color: Color.green);
    }
  }
}
