﻿using AsmodeeDigital.Common.Plugin.Domain.Data;
using AsmodeeDigital.Common.Plugin.Domain.Players;
using AsmodeeDigital.Common.Plugin.Manager.Event;
using AsmodeeDigital.Common.Plugin.Tests.Mocks;
using AsmodeeDigital.PlayReal.Plugin.Network;
using com.daysofwonder.async;
using NUnit.Framework;
using System.Collections.Generic;
using System.Threading;
using UnityEngine;

public class PlayReal_ServerConnection_Tests : ScriptableObject
{
    public DoWNetworkParameters networkParameters;

    public User Alice;
    public User Bob;
    public User Carol;

    [SetUp]
    public void InitializeTest()
    {
        EventManager.Instance = new EventManagerTest();
    }

    [Test]
    public void Authenticate()
    {
        ManualResetEvent manualEvent = new ManualResetEvent(false);
        bool authenticateCompleted = false;
        ServerConnection _srvCnx = new ServerConnection(networkParameters);

        _srvCnx.ConnectedToServerEvent += () =>
        {
            _srvCnx.AuthenticateUser(Alice.Login, Alice.Password, "SW", null);
        };

        _srvCnx.AsyncConnectedEvent += (a) =>
        {
            authenticateCompleted = true;
            _srvCnx.Disconnect();

            manualEvent.Set();
        };

        _srvCnx.AsyncConnectionErrorEvent += (a) =>
        {
            authenticateCompleted = false;
            _srvCnx.Disconnect();

            manualEvent.Set();
        };

        _srvCnx.Connect();
        bool timeOut = !manualEvent.WaitOne(1000, false);

        if (timeOut)
            throw new System.Exception("Time out");
        else
            Assert.IsTrue(authenticateCompleted);
    }

    [Test]
    public void CreateGameWithFriend()
    {
        ManualResetEvent manualEvent = new ManualResetEvent(false);
        bool succes = false;
        ServerConnection _srvCnx = new ServerConnection(networkParameters);

        _srvCnx.ConnectedToServerEvent += () =>
        {
            _srvCnx.AuthenticateUser(Alice.Login, Alice.Password, "SW", null);
        };

        _srvCnx.AsyncConnectedEvent += (a) =>
        {
            GameConfiguration gameConf = new GameConfiguration();
            gameConf.name = "Test CreateGameWithFriend";
            gameConf.timeout = 60;

            _srvCnx.CreateInvitationGame(gameConf, new List<int>() { Carol.DoWID });
        };

        _srvCnx.GameCreatedEvent += (g) =>
          {
              succes = true;

              manualEvent.Set();
          };

        _srvCnx.Connect();

        bool timeOut = !manualEvent.WaitOne(1000, false);

        _srvCnx.Disconnect();

        if (timeOut)
            throw new System.Exception("Time out");
        else
            Assert.IsTrue(succes);
    }

    [Test]
    public void GameAcceptedByFriend()
    {
        ManualResetEvent manualEvent = new ManualResetEvent(false);
        bool succes = false;

        //--- Alice
        ServerConnection _srvCnxAlice = new ServerConnection(networkParameters);

        _srvCnxAlice.ConnectedToServerEvent += () => { manualEvent.Set(); };
        _srvCnxAlice.AsyncConnectedEvent += (a) => { manualEvent.Set(); };
        _srvCnxAlice.InvitationAnsweredEvent += (i) => { succes = true; manualEvent.Set(); };
        //---

        //--- Bob
        GameCreatedRequest gameCreated = null;

        ServerConnection _srvCnxBob = new ServerConnection(networkParameters);

        _srvCnxBob.ConnectedToServerEvent += () => { manualEvent.Set(); };
        _srvCnxBob.GameCreatedEvent += (gameCreatedRequest) =>
        {
            gameCreated = gameCreatedRequest;
            manualEvent.Set();
        };
        //---

        _srvCnxAlice.Connect();
        manualEvent.WaitOne(1000, true);

        _srvCnxAlice.AuthenticateUser(Alice.Login, Alice.Password, "SW", null);
        manualEvent.Reset();
        manualEvent.WaitOne(1000, true);

        _srvCnxBob.Connect();
        manualEvent.Reset();
        manualEvent.WaitOne(1000, true);

        _srvCnxBob.AuthenticateUser(Bob.Login, Bob.Password, "SW", null);
        manualEvent.Reset();
        manualEvent.WaitOne(1000, true);

        GameConfiguration gameConf = new GameConfiguration();
        gameConf.name = "Test GameAcceptedByFriend";
        gameConf.timeout = 120;

        _srvCnxAlice.CreateInvitationGame(gameConf, new List<int>() { Bob.DoWID });

        manualEvent.Reset();
        manualEvent.WaitOne(1000, true);

        _srvCnxBob.AcceptInvitation(gameCreated.details.game_id);

        manualEvent.Reset();
        bool timeOut = !manualEvent.WaitOne(1000, false);

        _srvCnxAlice.Disconnect();
        _srvCnxBob.Disconnect();

        if (timeOut)
            throw new System.Exception("Time out");
        else
            Assert.IsTrue(succes);
    }
}