public SelectionState(Selection selection, bool fullSnapshot)
     : this()
 {
     Id = selection.Id;
     IsRollingSelection = selection is RollingSelection;
     Update(selection, fullSnapshot);
 }
        private bool TagEquals(string selectionIndexTag, KeyValuePair<string, string> tag, Selection selection)
        {
            var output = 
                //ignore selectiongroupid   
                tag.Key == "selectiongroupid" 
                //ignore index tag
                   || tag.Key == selectionIndexTag 
                //do comparison on all other tags (when they are passed in)
                   || (selection.Tags.ContainsKey(tag.Key) && string.Equals(selection.Tags[tag.Key], tag.Value, StringComparison.OrdinalIgnoreCase));

            return output;
        }
        public void GivenAFixtureWithTheFollowingMarkets(Table table)
        {
            ScenarioContext.Current.Clear();

            Fixture fixture = new Fixture { Id = "Test", MatchStatus = "40" };
            ScenarioContext.Current.Add("FIXTURE", fixture);

            foreach (var row in table.Rows)
            {
                Market mkt = new Market {Id = row["Market"]};
                mkt.AddOrUpdateTagValue("name", row["Name"]);

                fixture.Markets.Add(mkt);

                if (table.ContainsColumn("Selections"))
                {
                    int seln_count = Convert.ToInt32(row["Selections"]);
                    for (int i = 0; i < seln_count; i++)
                    {
                        Selection seln = new Selection { Name = row["Name"] + (i + 1) };
                        seln.Id = seln.Name;
                        mkt.Selections.Add(seln);
                    }
                }
            }
        }
        public void SerializeModelTest()
        {

            Fixture fixture = new Fixture
            {
                FixtureName = "TEST-NAME",
                Epoch = 10,
                LastEpochChangeReason = new[] { 10, 20 },
                Id = "TEST-ID",
                StartTime = new DateTime(2000, 01, 01),
                Sequence = 12,
                MatchStatus = "40"
            };
            fixture.Tags.Add("TEST-TAG-1", "1");
            fixture.Tags.Add("TEST-TAG-2", 2);
            fixture.GameState.Add("TEST-STATE-1", 1);
            fixture.GameState.Add("TEST-STATE-2", "2");

            Participant p1 = new Participant { Id = 1, Name = "P1" };
            p1.Tags.Add("TEST-TAG-1", "1");
            p1.Tags.Add("TEST-TAG-2", 2);

            Participant p2 = new Participant { Id = 2, Name = "P2" };

            fixture.Participants.Add(p1);
            fixture.Participants.Add(p2);

            Market mkt1 = new Market { Id = "MKT1" };
            mkt1.AddOrUpdateTagValue("name", "MKT1");

            Selection seln1 = new Selection
            {
                Id = "SELN1",
                Price = 2.0,
                Status = SelectionStatus.Active,
                Tradable = false
            };
            seln1.AddOrUpdateTagValue("name", "seln1");
            seln1.AddOrUpdateTagValue("displayed", "true");

            Selection seln2 = new Selection
            {
                Id = "SELN2",
                Price = 3.0,
                Status = SelectionStatus.Pending,
                Tradable = true
            };
            seln2.AddOrUpdateTagValue("name", "seln2");
            seln2.AddOrUpdateTagValue("displayed", "false");

            mkt1.Selections.Add(seln1);
            mkt1.Selections.Add(seln2);

            RollingMarket mkt2 = new RollingMarket { Id = "RMKT2", Line = 2.0 };
            mkt2.AddOrUpdateTagValue("name", "RMKT2");

            RollingSelection seln3 = new RollingSelection
            {
                Id = "SELN3",
                Price = 7.0,
                Status = SelectionStatus.Pending,
                Tradable = true,
                Line = 21
            };

            ((Market)mkt2).Selections.Add(seln3);
            Market test2 = mkt2;
            test2.Selections.Count.Should().Be(1);
            (test2.Selections.FirstOrDefault() is RollingSelection).Should().BeTrue();

            Market mkt3 = new RollingMarket();
            mkt3.Id = "RMKT3";
            mkt3.AddOrUpdateTagValue("name", "RMKT3");

            fixture.Markets.Add(mkt1);
            fixture.Markets.Add(mkt2);
            fixture.Markets.Add(mkt3);

            fixture.RollingMarkets.FirstOrDefault(x => x.Id == "MKT1").Should().BeNull();
            fixture.RollingMarkets.FirstOrDefault(x => x.Id == "RMKT2").Should().NotBeNull();
            fixture.RollingMarkets.FirstOrDefault(x => x.Id == "RMKT3").Should().NotBeNull();

            fixture.StandardMarkets.FirstOrDefault(x => x.Id == "MKT1").Should().NotBeNull();
            fixture.StandardMarkets.FirstOrDefault(x => x.Id == "RMKT2").Should().BeNull();
            fixture.StandardMarkets.FirstOrDefault(x => x.Id == "RMKT3").Should().BeNull();

            string value = FixtureJsonHelper.ToJson(fixture);
            using (var stream = new MemoryStream(Encoding.UTF8.GetBytes(value)))
            {

                stream.Position = 0;
                string value2 = Encoding.UTF8.GetString(stream.ToArray());

                value.Should().BeEquivalentTo(value2);

                fixture = FixtureJsonHelper.GetFromJson(value2);
            }

            fixture.RollingMarkets.Count().Should().Be(2);
            fixture.StandardMarkets.Count().Should().Be(1);
            fixture.Markets.Count().Should().Be(3);
            fixture.Tags.Count.Should().Be(2);
            fixture.GameState.Count().Should().Be(2);
            fixture.Participants.Count().Should().Be(2);

            fixture.Markets.FirstOrDefault(x => x.Id == "MKT1").Selections.Count.Should().Be(2);
            fixture.Markets.FirstOrDefault(x => x.Id == "RMKT2").Selections.Count.Should().Be(1);
            fixture.Markets.FirstOrDefault(x => x.Id == "RMKT3").Selections.Count.Should().Be(0);

            BinaryStoreProvider<Fixture> provider = new BinaryStoreProvider<Fixture>(".", "test-{0}.dat");

            provider.SetObject("TEST", fixture);

            fixture = provider.GetObject("TEST");

            fixture.RollingMarkets.Count().Should().Be(2);
            fixture.StandardMarkets.Count().Should().Be(1);
            fixture.Markets.Count().Should().Be(3);
            fixture.Tags.Count.Should().Be(2);
            fixture.GameState.Count().Should().Be(2);
            fixture.Participants.Count().Should().Be(2);

            fixture.Markets.FirstOrDefault(x => x.Id == "MKT1").Selections.Count.Should().Be(2);
            fixture.Markets.FirstOrDefault(x => x.Id == "RMKT2").Selections.Count.Should().Be(1);
            fixture.Markets.FirstOrDefault(x => x.Id == "RMKT3").Selections.Count.Should().Be(0);

            fixture = value.FromJson<Fixture>();

            fixture.RollingMarkets.Count().Should().Be(2);
            fixture.StandardMarkets.Count().Should().Be(1);
            fixture.Markets.Count().Should().Be(3);
            fixture.Tags.Count.Should().Be(2);
            fixture.GameState.Count().Should().Be(2);
            fixture.Participants.Count().Should().Be(2);

            fixture.Markets.FirstOrDefault(x => x.Id == "MKT1").Selections.Count.Should().Be(2);
            fixture.Markets.FirstOrDefault(x => x.Id == "RMKT2").Selections.Count.Should().Be(1);
            fixture.Markets.FirstOrDefault(x => x.Id == "RMKT3").Selections.Count.Should().Be(0);
        }
        public void SelectionResulStateTest()
        {
            Market mkt = new Market("123");

            var seln = new Selection()
            {
                Id = "A1",
                Result = new Result()
                {
                    StakeParticipants = 1,
                    StakePlaces = 2,
                    WinParticipants = 3,
                    WinPlaces = 4
                }
            };

            mkt.Selections.Add(seln);

            Fixture fxt = new Fixture()
            {
                Id = "FXT",
                FixtureName = "TestSelectionResultTest",
                MatchStatus = "40",
            };

            fxt.Markets.Add(mkt);

            MarketStateCollection collection = new MarketStateCollection("FXT");
            collection.Update(fxt, true);

            var model = collection["123"]["A1"].Result as SelectionResultState;
            model.Should().NotBeNull();

            model.IsEquivalentTo(seln.Result).Should().BeTrue();

            var clone = model.Clone();
            model.IsEqualTo(clone).Should().BeTrue();

            seln.Result.WinParticipants = 2;
            model.IsEquivalentTo(seln.Result).Should().BeFalse();

        }
        private void UpdateLineOnRollingSelection(Selection selection)
        {
            var rollingSelection = selection as RollingSelection;
            if(rollingSelection == null) 
                return;

            this.Line = rollingSelection.Line;
        }
        public void Update(Selection selection, bool fullSnapshot)
        {
            Price = selection.Price;
            Status = selection.Status;
            Tradability = selection.Tradable;

            if (fullSnapshot)
            {
                _tags = new Dictionary<string, string>(StringComparer.InvariantCultureIgnoreCase);

                foreach (var key in selection.TagKeys)
                    _tags.Add(key, selection.GetTagValue(key));

                Name = selection.Name;

                // Result and PlaceResult (in the context of racing fixtures) 
                // are only present on a full snapshot
                if (selection.Result != null)
                {
                    if (Result == null)
                        Result = new SelectionResultState(selection.Result);
                    else
                        ((IUpdatableSelectionResultState)Result).Update(selection.Result);
                }

                if (selection.PlaceResult != null)
                {
                    if (PlaceResult == null)
                        PlaceResult = new SelectionResultState(selection.PlaceResult);
                    else
                        ((IUpdatableSelectionResultState)PlaceResult).Update(selection.PlaceResult);
                }
            }

            UpdateLineOnRollingSelection(selection);
        }
        public bool IsEquivalentTo(Selection selection, bool checkTags)
        {
            if (selection == null)
                return false;

            if (selection.Id != Id)
                return false;

            if (checkTags)
            {
                if (selection.TagsCount != TagsCount)
                    return false;


                if (selection.TagKeys.Any(tag => !HasTag(tag) || GetTagValue(tag) != selection.GetTagValue(tag)))
                    return false;

                // if we are here, there is no difference between the stored tags
                // and those contained within the selection object...
                // we can then proceed to check the selection's fields
                // Note that Selection.Name is a shortcut for Selection.GetTagValue("name")

                // as Result and PlaceResult are only present when dealing with full snapshots
                // we only check these properties if checkTags is true

                if (selection.Result != null)
                {
                    if (Result == null)
                        return false;

                    if (!Result.IsEquivalentTo(selection.Result))
                        return false;
                }

                if (selection.PlaceResult != null)
                {
                    if (PlaceResult == null)
                        return false;

                    if (!PlaceResult.IsEquivalentTo(selection.PlaceResult))
                        return false;
                }
            }

            var result = Price == selection.Price &&
                         Status == selection.Status &&
                         Tradability == selection.Tradable;

            
            if (IsRollingSelection)
                return result &= Line == ((RollingSelection)selection).Line;

            return result;
        }
        public void DeltaRuleWithMarketSeverity()
        {
            // STEP 1: prepare stub data
            var settings = new Mock<ISettings>();
            var plugin = new Mock<IAdapterPlugin>();
            var stateprovider = new StateManager(settings.Object, plugin.Object);

            DeltaRule.Instance.Severity = DeltaRule.DeltaRuleSeverity.REMOVE_MARKETS;

            List<IMarketRule> rules = new List<IMarketRule> { DeltaRule.Instance };

            // STEP 2: prepare fixture data
            // Fixture
            //  - MKT1
            //  -- SELN_1_1
            //  -- SELN_1_2
            //  - MKT2
            //  -- SELN_2_1
            //  -- SELN_2_2

            Fixture fixture = new Fixture { Id = "TestId", MatchStatus = "40" };
            fixture.Tags.Add("Sport", "Football");

            Market mkt = new Market { Id = "MKT1" };
            mkt.AddOrUpdateTagValue("name", "mkt1");
            mkt.AddOrUpdateTagValue("type", "type1");

            Selection seln = new Selection { Id = "SELN_1_1" };
            seln.AddOrUpdateTagValue("name", "seln_1_1");
            seln.Tradable = true;
            seln.Status = SelectionStatus.Active;
            seln.Price = 0.1;

            mkt.Selections.Add(seln);

            seln = new Selection { Id = "SELN_1_2" };
            seln.AddOrUpdateTagValue("name", "seln_1_2");
            seln.Tradable = true;
            seln.Status = SelectionStatus.Active;
            seln.Price = 0.2;

            mkt.Selections.Add(seln);

            fixture.Markets.Add(mkt);

            mkt = new Market { Id = "MKT2" };
            mkt.AddOrUpdateTagValue("name", "mkt2");
            mkt.AddOrUpdateTagValue("type", "type2");

            seln = new Selection { Id = "SELN_2_1" };
            seln.AddOrUpdateTagValue("name", "seln_2_1");
            seln.Tradable = false;
            seln.Status = SelectionStatus.Pending;
            seln.Price = null;

            mkt.Selections.Add(seln);

            seln = new Selection { Id = "SELN_2_2" };
            seln.AddOrUpdateTagValue("name", "seln_2_2");
            seln.Tradable = false;
            seln.Status = SelectionStatus.Pending;
            seln.Price = null;

            mkt.Selections.Add(seln);

            fixture.Markets.Add(mkt);

            // STEP 3: invoke the delta rule
            MarketRulesManager manager = new MarketRulesManager(fixture.Id, stateprovider, rules);

            manager.ApplyRules(fixture); // this will not have any effect as we don't have any state yet

            manager.CommitChanges();

            manager.ApplyRules(fixture); // here is where the delta rule is invoked (note that we haven't changed anything on the fixture)

            manager.CommitChanges();

            // STEP 4: check the results (delta rule should have removed everything)
            fixture.Markets.Count.Should().Be(0);

            // STEP 5: change a single field
            seln.Price = 1.2;
            fixture.Markets.Add(mkt);
            mkt.Selections.Count().Should().Be(2);

            // STEP 6: apply the delta rule again
            manager.ApplyRules(fixture);

            // STEP 7: the market should not have been filtered out
            fixture.Markets.Count().Should().Be(1);
            fixture.Markets[0].Selections.Count().Should().Be(2);
        }