// Copyright (c) 2023 Timothy Schenk. Subject to the GNU AGPL Version 3 License.

using System.Net;
using System.Net.Sockets;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using NetCoreServer;

namespace Continuity.AuthServer.Services;

public class WonderkingAuthServer : TcpServer, IHostedService
{
    private readonly ILogger<WonderkingAuthServer> _logger;
    private readonly IServiceProvider _serviceProvider;

    public WonderkingAuthServer(IPAddress address, int port, ILogger<WonderkingAuthServer> logger,
        IServiceProvider serviceProvider) : base(address, port)
    {
        _logger = logger;
        _serviceProvider = serviceProvider;
    }

    public Task StartAsync(CancellationToken cancellationToken)
    {
        Start();
        return Task.CompletedTask;
    }

    public Task StopAsync(CancellationToken cancellationToken)
    {
        DisconnectAll();
        Stop();
        return Task.CompletedTask;
    }

    protected override TcpSession CreateSession()
    {
        return ActivatorUtilities.CreateInstance<AuthSession>(_serviceProvider, this);
    }

    protected override void OnStarting()
    {
        _logger.LogInformation("Starting");
        base.OnStarting();
    }

    protected override void OnStarted()
    {
        _logger.LogInformation("Started");
        base.OnStarted();
    }

    protected override void OnStopping()
    {
        _logger.LogInformation("Stopping");
        base.OnStopping();
    }

    protected override void OnStopped()
    {
        _logger.LogInformation("Stopped");
        base.OnStopped();
    }

    protected override void OnConnected(TcpSession session)
    {
        _logger.LogInformation("Client connected {Session}", session.Id);
        base.OnConnected(session);
    }

    protected override void OnDisconnected(TcpSession session)
    {
        _logger.LogInformation("Client disconnected {Session}", session.Id);
        base.OnDisconnected(session);
    }

    protected override void OnError(SocketError error)
    {
        _logger.LogError("An error has occured {Error}", error);
    }
}