private NetworkMessenger()
        {
            this.gate                   = new SemaphoreSlim(1, 1);
            this.messagePipeline        = new Subject <NetworkMessage>();
            this.disconnected           = new Subject <Unit>();
            this.connectionEstablished  = new Subject <Unit>();
            this.connectionInfoReceived = new Subject <ConnectionInfo>();

            this.client = new Subject <ITcpClient>();

            this.isConnected = this.Disconnected.Select(_ => false)
                               .Merge(this.connectionEstablished.Select(_ => true))
                               .StartWith(false)
                               .Do(x => this.Log().Info("Connection status: {0}", x ? "Connected" : "Disconnected"))
                               .ToProperty(this, x => x.IsConnected);
            var connectConn = this.IsConnected;

            var pipeline = this.client.Select(x => Observable.Defer(() => x.GetStream().ReadNextMessageAsync()
                                                                    .ToObservable())
                                              .Repeat()
                                              .LoggedCatch(this, null, "Error while reading the next network message")
                                              .TakeWhile(m => m != null)
                                              .TakeUntil(this.Disconnected))
                           .Switch()
                           .Publish();

            this.messagePipeline           = pipeline.ObserveOn(RxApp.TaskpoolScheduler);
            this.messagePipelineConnection = pipeline.Connect();

            var pushMessages = this.messagePipeline.Where(x => x.MessageType == NetworkMessageType.Push)
                               .Select(x => x.Payload.ToObject <PushInfo>());

            this.PlaylistChanged = pushMessages.Where(x => x.PushAction == PushAction.UpdateCurrentPlaylist)
                                   .Select(x => x.Content.ToObject <NetworkPlaylist>());

            this.PlaybackStateChanged = pushMessages.Where(x => x.PushAction == PushAction.UpdatePlaybackState)
                                        .Select(x => x.Content["state"].ToObject <NetworkPlaybackState>());

            this.PlaybackTimeChanged = pushMessages.Where(x => x.PushAction == PushAction.UpdateCurrentPlaybackTime)
                                       .Select(x => x.Content["currentPlaybackTime"].ToObject <TimeSpan>());

            var settings = Locator.Current.GetService <UserSettings>();

            if (settings == null)
            {
                throw new InvalidOperationException("No user settings registered!");
            }

            this.accessPermission = pushMessages.Where(x => x.PushAction == PushAction.UpdateAccessPermission)
                                    .Select(x => x.Content["accessPermission"].ToObject <NetworkAccessPermission>())
                                    .Merge(this.connectionInfoReceived.Select(x => x.AccessPermission))
                                    .Select(x => TrialHelpers.GetAccessPermissionForPremiumState(x, settings.IsPremium ||
                                                                                                 TrialHelpers.IsInTrialPeriod(AppConstants.TrialTime)))
                                    .ToProperty(this, x => x.AccessPermission);
            var connectAccessPermission = this.AccessPermission;

            this.guestSystemInfo = pushMessages.Where(x => x.PushAction == PushAction.UpdateGuestSystemInfo)
                                   .Select(x => x.Content.ToObject <GuestSystemInfo>())
                                   .Merge(this.connectionInfoReceived.Select(x => x.GuestSystemInfo))
                                   .ToProperty(this, x => x.GuestSystemInfo);
            var connectGuestSystemInfo = this.GuestSystemInfo;
        }
 public void PremiumAndAdminReturnsAdmin()
 {
     Assert.Equal(NetworkAccessPermission.Admin,
                  TrialHelpers.GetAccessPermissionForPremiumState(NetworkAccessPermission.Admin, true));
 }
 public void PremiumAndGuestReturnsGuest()
 {
     Assert.Equal(NetworkAccessPermission.Guest,
                  TrialHelpers.GetAccessPermissionForPremiumState(NetworkAccessPermission.Guest, true));
 }
 public void NotPremiumAndAdminReturnsGuest()
 {
     Assert.Equal(NetworkAccessPermission.Guest,
                  TrialHelpers.GetAccessPermissionForPremiumState(NetworkAccessPermission.Admin, false));
 }