context: ///////////////////////////////////////////////////////////////////////////////////////
  // Copyright (C) 2006-2015 Esper Team. All rights reserved.                           /
  // http://esper.codehaus.org                                                          /
  // ---------------------------------------------------------------------------------- /
  // The software in this package is published under the terms of the GPL license       /
  // a copy of which has been included with this distribution in the license.txt file.  /
  ///////////////////////////////////////////////////////////////////////////////////////
  
  using System;
  using System.Collections.Generic;
  
  using com.espertech.esper.common.client.util;
  using com.espertech.esper.common.@internal.bytecodemodel.@base;
  using com.espertech.esper.common.@internal.bytecodemodel.model.expression;
  using com.espertech.esper.common.@internal.support;
  using com.espertech.esper.compat;
  using com.espertech.esper.compat.collections;
  using com.espertech.esper.regressionlib.framework;
  using com.espertech.esper.regressionlib.support.bean;
  
  using NUnit.Framework;
  
  using static com.espertech.esper.common.@internal.bytecodemodel.model.expression.CodegenExpressionBuilder;
  using static com.espertech.esper.regressionlib.framework.SupportMessageAssertUtil;
  
  namespace com.espertech.esper.regressionlib.suite.infra.tbl
  {
      /// <summary>
      ///     NOTE: More table-related tests in "nwtable"
      /// </summary>
      public class InfraTableCountMinSketch
      {
          public static IList<RegressionExecution> Executions()
          {
              var execs = new List<RegressionExecution>();
              WithFrequencyAndTopk(execs);
              WithDocSamples(execs);
              WithNonStringType(execs);
              WithInvalid(execs);
              return execs;
          }
  
          public static IList<RegressionExecution> WithInvalid(IList<RegressionExecution> execs = null)
          {
              execs = execs ?? new List<RegressionExecution>();
              execs.Add(new InfraInvalid());
              return execs;
          }
  
          public static IList<RegressionExecution> WithNonStringType(IList<RegressionExecution> execs = null)
          {
              execs = execs ?? new List<RegressionExecution>();
              execs.Add(new InfraNonStringType());
              return execs;
          }
  
          public static IList<RegressionExecution> WithDocSamples(IList<RegressionExecution> execs = null)
          {
              execs = execs ?? new List<RegressionExecution>();
              execs.Add(new InfraDocSamples());
              return execs;
          }
  
          public static IList<RegressionExecution> WithFrequencyAndTopk(IList<RegressionExecution> execs = null)
          {
              execs = execs ?? new List<RegressionExecution>();
              execs.Add(new InfraFrequencyAndTopk());
              return execs;
          }
  
          private static void AssertOutput(
              RegressionEnvironment env,
              string frequencyList,
              string topkList)
          {
              AssertFrequencies(env, frequencyList);
              AssertTopk(env, topkList);
          }
  
          private static void AssertFrequencies(
              RegressionEnvironment env,
              string frequencyList)
          {
              var pairs = frequencyList.SplitCsv();
              for (var i = 0; i < pairs.Length; i++) {
                  var split = pairs[i].Split('=');
                  env.SendEventBean(new SupportBean_S0(0, split[0].Trim()));
                  var value = env.Listener("frequency").AssertOneGetNewAndReset().Get("freq");
                  Assert.AreEqual(long.Parse(split[1]), value, "failed at index" + i);
              }
          }
  
          private static void AssertTopk(
              RegressionEnvironment env,
              string topkList)
          {
              env.SendEventBean(new SupportBean_S1(0));
              var @event = env.Listener("topk").AssertOneGetNewAndReset();
              var arr = (CountMinSketchTopK[]) @event.Get("topk");
  
              var pairs = topkList.SplitCsv();
              Assert.AreEqual(pairs.Length, arr.Length, "received " + Arrays.AsList(arr));
  
              foreach (var pair in pairs) {
                  var pairArr = pair.Split('=');
                  var expectedFrequency = long.Parse(pairArr[1]);
                  var expectedValue = pairArr[0].Trim();
                  var foundIndex = Find(expectedFrequency, expectedValue, arr);
                  Assert.IsFalse(
                      foundIndex == -1,
                      "failed to find '" +
                      expectedValue +
                      "=" +
                      expectedFrequency +
                      "' among remaining " +
                      Arrays.AsList(arr));
                  arr[foundIndex] = null;
              }
          }
  
          private static int Find(
              long expectedFrequency,
              string expectedValue,
              CountMinSketchTopK[] arr)
          {
              for (var i = 0; i < arr.Length; i++) {
                  var item = arr[i];
                  if (item != null && item.Frequency == expectedFrequency && item.Value.Equals(expectedValue)) {
                      return i;
                  }
              }
  
              return -1;
          }
  
          internal class InfraDocSamples : RegressionExecution
          {
              public void Run(RegressionEnvironment env)
              {
                  var path = new RegressionPath();
                  env.CompileDeploy("create schema WordEvent (word string)", path);
                  env.CompileDeploy("create schema EstimateWordCountEvent (word string)", path);
  
                  env.CompileDeploy("create table WordCountTable(wordcms countMinSketch())", path);
                  env.CompileDeploy(
                      "create table WordCountTable2(wordcms countMinSketch({\n" +
                      "  EpsOfTotalCount: 0.000002,\n" +
                      "  Confidence: 0.999,\n" +
                      "  Seed: 38576,\n" +
                      "  Topk: 20,\n" +
                      "  Agent: '" +
                      typeof(CountMinSketchAgentStringUTF16Forge).FullName +
                      "'" +
                      "}))",
                      path);
                  env.CompileDeploy(
                      "into table WordCountTable select countMinSketchAdd(word) as wordcms from WordEvent",
                      path);
                  env.CompileDeploy(
                      "select WordCountTable.wordcms.countMinSketchFrequency(word) from EstimateWordCountEvent",
                      path);
                  env.CompileDeploy(
                      "select WordCountTable.wordcms.countMinSketchTopk() from pattern[every timer:interval(10 sec)]",
                      path);
  
                  env.UndeployAll();
              }
          }
  
          internal class InfraNonStringType : RegressionExecution
          {
              public void Run(RegressionEnvironment env)
              {
                  var path = new RegressionPath();
                  var eplTable = "create table MyApproxNS(bytefreq countMinSketch({" +
                                 "  EpsOfTotalCount: 0.02," +
                                 "  Confidence: 0.98," +
                                 "  Topk: null," +
                                 "  Agent: '" +
                                 typeof(MyBytesPassthruAgentForge).FullName +
                                 "'" +
                                 "}))";
                  env.CompileDeploy(eplTable, path);
  
                  var eplInto =
                      "into table MyApproxNS select countMinSketchAdd(Body) as bytefreq from SupportByteArrEventStringId(Id='A')";
                  env.CompileDeploy(eplInto, path);
  
                  var eplRead =
                      "@Name('s0') select MyApproxNS.bytefreq.countMinSketchFrequency(Body) as freq from SupportByteArrEventStringId(Id='B')";
                  env.CompileDeploy(eplRead, path).AddListener("s0");
  
                  env.SendEventBean(new SupportByteArrEventStringId("A", new byte[] {1, 2, 3}));
  
                  env.Milestone(0);
  
                  env.SendEventBean(new SupportByteArrEventStringId("B", new byte[] {0, 2, 3}));
                  Assert.AreEqual(0L, env.Listener("s0").AssertOneGetNewAndReset().Get("freq"));
  
                  env.SendEventBean(new SupportByteArrEventStringId("B", new byte[] {1, 2, 3}));
                  Assert.AreEqual(1L, env.Listener("s0").AssertOneGetNewAndReset().Get("freq"));
  
                  env.UndeployAll();
              }
          }
  
          internal class InfraFrequencyAndTopk : RegressionExecution
          {
              public void Run(RegressionEnvironment env)
              {
                  var path = new RegressionPath();
                  var epl =
                      "create table MyApproxFT(wordapprox countMinSketch({topk:3}));\n" +
                      "into table MyApproxFT select countMinSketchAdd(TheString) as wordapprox from SupportBean;\n" +
                      "@Name('frequency') select MyApproxFT.wordapprox.countMinSketchFrequency(P00) as freq from SupportBean_S0;\n" +
                      "@Name('topk') select MyApproxFT.wordapprox.countMinSketchTopk() as topk from SupportBean_S1;\n";
                  env.CompileDeploy(epl, path).AddListener("frequency").AddListener("topk");
  
                  env.SendEventBean(new SupportBean("E1", 0));
                  AssertOutput(env, "E1=1", "E1=1");
  
                  env.Milestone(0);
  
                  AssertOutput(env, "E1=1", "E1=1");
  
gt:                 env.SendEventBean(new SupportBean("E2", 0));