using System;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
using Connexion.Core;
using Connexion.Core.HL7;
using Connexion.Share;
using Cxn.Queue.Mongo;
using MongoDB.Bson;

namespace MongoPerfTest
{
  internal class Program
  {
    private static void Main(string[] args)
    {
      var t = new MongoTester();
      t.Start();
      Console.ReadLine();
      t.Stop();
    }
  }

  public class MongoTester
  {
    private const string hl7 =
    @"MSH|^~\&|EPIC|UCHC|PACS|UCHC|20110111204758||ADT^A08|9701466|P|2.2|" +
    "EVN||201012221745|" +
    "PID|||100001||CIERS^HANH^CHANTAY|^^CIERS|19340901|F||U|6834 RIO ESTRADA WAY^^SLC^UT^60561^USA^^SALT LAKE||(408)-131-3279|(408)-389-4489||||872-39-1819|872-39-1819||||||||||" +
    "PV1||O|NEPH^^|||^^|2190^TESTA^GIULIANO^^^|308447^ABBO^PAUL^R^^||TRP||||||||||BLUE CROSS||||||||||||||||||||||||201101111454|" +
    "IN1|1|BC-PPO^|BLUE CROSS OF ILLINOIS||||(408)-374-7817|941-53-6056||||||||KORTHAUER^MISHA^GIHANHA|||953 BENBROOK LANE^^BURBANK^CA^^USA^^LOS ANGELES";

    private const string mm = @"{""CreatedDateTime"":""2015-02-17T22:23:19.6979834Z"",""Keywords"":[{""Key"":""__1"",""Value"":""IHS-20110601061000.00010""},{""Key"":""__2"",""Value"":""333-31-7085""},{""Key"":""__3"",""Value"":""ORU^R01""},{""Key"":""__4"",""Value"":""50217142319.10""},{""Key"":""__5"",""Value"":""5021714231910""},{""Key"":""__6"",""Value"":""634425054000000000""},{""Key"":""0"",""Value"":""333-31-7085""},{""Key"":""1"",""Value"":""110601011000.10""}],""Data"":""MSH|^~\\&|ADM|SHM|ALL|ALL|20110601061000.00||ORU^R01|IHS-20110601061000.00010|P|2.1\rPID|1||50217142319.10||SPICKLER^REVA^LOUELLA^^^DED||19721110|F|||9963 PORT PACIFIC LN^MOFFAT^DINOSAUR^CO^81610^|||||||333-31-7085|333-31-7085\rPV1|1|I|P186^R4^B5|C|||333-48-4250^NEWYEAR^AUGUST^LOYD^MD^DR|490-87-9670^SHAMI^ELIAS^SANDY^MD^DR||||||3||||IN||||||||||||||||||||||||||20110601120500\rNK1|1|SPICKLER^NORMA^EMILIE^^^CMA|MO\rIN1|1|TRICARE||||||||||||||SPICKLER^REVA^LOUELLA^^^DED|SELF\rORC|RE|110601011000.10|||CM||||20110601011000|879-13-5522^BERTOTTI^MINERVA^BILLYE^MD^DR||558-69-3784^GABRIELE^DANNIE^EDGARDO^MD^DR\rOBR||110601011000.10|5021714231910|^||||||||||||558-69-3784^GABRIELE^DANNIE^EDGARDO^MD^DR|(408)-822-3953||||||||F|||||||259-65-6700&VANVUREN&IRWIN&FEDERICO&MD&DR|259-65-6700&VANVUREN&IRWIN&FEDERICO&MD&DR||380-70-2600&MASSENGILL&GONZALO&JORDON&MD&DR|20110601011000\rOBX|1|TX|||Results for patient: REVA SPICKLER||||||F\rOBX|2|TX|||Exam 20110601011000: ||||||F\rOBX|3|TX|||Referring Physician: Dr. ELIAS, SHAMI||||||F\rOBX|4|TX|||Attending Physician: Dr. AUGUST, NEWYEAR||||||F\rOBX|5|TX|||Principal Result Interpreter: Dr. IRWIN, VANVUREN||||||F\r"",""DataSize"":1143,""DataType"":""Connexion.Share.HL7MessageFactory"",""QueueType"":""Queued"",""ProcessingHistories"":[]}";

    const int _numQueues = 50;
    private List<MongoQueue> _Queues;
    private CancellationTokenSource _cts;

    public void Start()
    {
      _cts = new CancellationTokenSource();
      _Queues = new List<MongoQueue>(_numQueues);
      InitQueues();
      StartQueuing();
    }

    public void Stop()
    {
      _cts.Cancel();
      if (_Queues != null)
      {
        _Queues.ForEach(q => q.Stop());
        _Queues.Clear();
      }
    }

    private void InitQueues()
    {
      var cfg = new QueueDeviceConfiguration
      {
        MongoDataPath = "e:\\mongo",
        MongoHost = "localhost",
        MongoPort = 27017,
      };

      for (var i = 0; i < _numQueues; i++)
      {
        var guid = Guid.NewGuid();
        var q = _Queues.AddWithReturn(new MongoQueue(guid, cfg));
        q.Start();
      }
    }

    private void StartQueuing()
    {
      foreach (var q in _Queues)
      {
        QueueMessages(q);
      }
    }

    private async Task QueueMessages(MongoQueue q)
    {
      var msg = Serialization.Deserialize<MongoMessage>(mm);
      while (true)
      {
        if (_cts.IsCancellationRequested)
          return;

        var m = new MongoMessage
        {
          AttachmentBytes = msg.AttachmentBytes,
          AttachmentSize = msg.AttachmentSize,
          ChildBytes = msg.ChildBytes,
          ChildObjectIds = msg.ChildObjectIds,
          CorrelationKey = msg.CorrelationKey,
          CreatedDateTime = DateTime.UtcNow,
          Data = msg.Data,
          DataSize = msg.DataSize,
          DataType = msg.DataType,
          HasProcessingHistory = msg.HasProcessingHistory,
          Keywords = msg.Keywords,
          ModifiedDateTime = null,
          QueueType = QueueType.Queued,
          SourceDeviceKey = msg.SourceDeviceKey,
          SourceUri = msg.SourceUri,
        };

        await q.QueueMessage(m);
      }
    }


  }
}
