using BenchmarkDotNet.Mathematics;
using BenchmarkDotNet.Mathematics.StatisticalTesting;
using JetBrains.Annotations;
using Xunit;
using Xunit.Abstractions;

namespace BenchmarkDotNet.Tests.Mathematics.StatisticalTesting
{
    public class StudentTests
    {
        private readonly ITestOutputHelper output;

        public StudentTests(ITestOutputHelper output) => this.output = output;

        [Fact]
        public void Student30Test()
        {
            // set.seed(42); x <- rnorm(30, mean = 10)
            double[] x =
            {
                11.370958, 9.435302, 10.363128, 10.632863, 10.404268, 9.893875, 11.511522, 9.905341, 12.018424, 9.937286,
                11.304870, 12.286645, 8.611139, 9.721211, 9.866679, 10.635950, 9.715747, 7.343545, 7.559533, 11.320113,
                9.693361, 8.218692, 9.828083, 11.214675, 11.895193, 9.569531, 9.742731, 8.236837, 10.460097, 9.360005
            };
            Check(x, 9, 0);
            Check(x, 10, 0.3834);
            Check(x, 11, 0.9998);
        }

        [Fact]
        public void Student300Test()
        {
            double[] x =
            {
                101.370958447147, 99.4353018286039, 100.363128411337, 100.632862604961, 100.404268323141, 99.8938754839085,
                101.511521997439, 99.9053409615869, 102.018423713877, 99.9372859009476, 101.304869654223, 102.286645392701,
                98.6111392988877, 99.7212112331826, 99.8666786636063, 100.63595039807, 99.7157470785839, 97.3435445790952,
                97.5595330714245, 101.32011334573, 99.6933614059215, 98.21869156602, 99.8280826442404, 101.214674699173,
                101.895193461265, 99.5695308683938, 99.7427306172311, 98.2368369148052, 100.460097354831, 99.3600051240399,
                100.455450123241, 100.704837337229, 101.03510352197, 99.3910736245928, 100.504955123298, 98.2829913209267,
                99.2155409916205, 99.1490924058235, 97.5857923500534, 100.036122606892, 100.2059986002, 99.6389427014513,
                100.7581632357, 99.2732951729234, 98.6317189555807, 100.432818025889, 99.1886068238133, 101.444101261721,
                99.5685537973867, 100.655647883402, 100.321925265204, 99.2161610591196, 101.575727519792, 100.642899305717,
                100.0897606466, 100.276550747291, 100.679288816055, 100.089832886579, 97.0069099168471, 100.284882953531,
                99.632765357259, 100.185230564866, 100.581823727366, 101.399736827293, 99.2727079405255, 101.302542632044,
                100.335848119752, 101.038506098698, 100.920728568291, 100.720878162867, 98.9568810614321, 99.9098136133893,
                100.623518162, 99.0464766422277, 99.4571711854261, 100.580996497682, 100.768178737835, 100.46376758854,
                99.1142237025903, 98.9002191013521, 101.512707009805, 100.257921437532, 100.08844022916, 99.8791034624609,
                98.8056711048395, 100.61199689804, 99.7828601542535, 99.8172432936681, 100.933346328571, 100.821773110508,
                101.392116375934, 99.5238260769453, 100.650348560726, 101.39111045639, 98.8892111205521, 99.1392074131222,
                98.8682613191462, 98.5407860004976, 100.079982553241, 100.653204339649, 101.200965375598, 101.044751087168,
                98.9967913531601, 101.848481901673, 99.3332265912422, 100.105513812456, 99.5777441181312, 99.877649828045,
                100.188193034501, 100.119160957997, 99.9749074491326, 100.108072727942, 99.5145647641533, 99.4957828693121,
                98.3389009200852, 99.6176662731262, 99.4873497421222, 102.701891000345, 98.6378837688103, 100.137256218559,
                98.5063749326837, 98.5295642585632, 100.124702386197, 99.003360865116, 99.9981773856953, 99.5717411185742,
                99.3863283935505, 97.9753221545809, 98.77525204964, 100.179516441118, 100.567620594424, 99.5071226464465,
                100.000062884065, 101.12288964338, 101.439855742976, 98.9028862315942, 99.8826804397498, 101.20149840092,
                99.5302704194337, 99.947530515061, 99.9138927017629, 99.1123209820936, 99.5553159951153, 99.9705551209118,
                99.5861311509421, 101.113386023368, 99.519007158346, 99.5668309673993, 100.696862576552, 98.9436315868291,
                99.9593015248488, 98.4484551776524, 101.167169549236, 99.7263542986259, 99.5321546753277, 98.7617476720138,
                99.9922379662227, 99.1997178220483, 99.4665076700496, 101.287675245585, 99.8244741297579, 98.9282176158493,
                100.163206882467, 99.6372615843721, 100.590013547987, 101.432421927731, 99.0073074888905, 100.45465029758,
                100.084898058678, 100.895565582265, 99.7702218610537, 100.836619068461, 98.2549441386633, 101.689458921313,
                100.864777978519, 99.8492240111143, 98.5509928698608, 100.643008700042, 100.483193863815, 99.9936443735786,
                100.151455892862, 99.4158910296502, 100.36880673263, 100.29465433972, 99.7207406266574, 98.6637633451068,
                100.70074881844, 100.554196622274, 99.1636934071986, 98.4054118379938, 100.204958580588, 99.6549120220271,
                100.252611703364, 98.7059975345154, 99.0408295556196, 101.08577485368, 100.403774904716, 100.586487536719,
                101.815228446154, 100.128821428602, 97.9990707622685, 100.333777197434, 101.171325127359, 102.059539242299,
                98.6231384017595, 98.8491444343729, 99.2941786052399, 98.9459442179228, 99.3542562768575, 99.8146220323235,
                98.79877794926, 102.036972166983, 100.107774744886, 99.9158918994944, 100.495619641605, 100.037415186118,
                99.8679119630441, 101.476787423552, 99.7829697899079, 98.7163977959078, 100.385667890443, 99.6484871264709,
                99.4782039066437, 98.9318687993128, 100.428365903267, 99.825981765573, 100.515667728648, 99.7656347226941,
                99.3414965741782, 101.250236604079, 99.7282362848886, 100.947951995875, 98.7984175698911, 99.5338839036245,
                99.7306486048468, 99.6090345918691, 101.348707011992, 99.9772352987016, 100.244225851103, 99.0576282921361,
                99.2707827234904, 100.998068908555, 101.258481664596, 101.24886368881, 98.6193629504747, 102.049960693636,
                101.0168728298, 99.9732825358617, 100.703607778798, 99.0286147708481, 98.9038437584411, 100.049050450938,
                98.8015041434422, 100.19001899856, 101.297705899605, 98.9661262770352, 99.2615592457869, 100.046563939451,
                98.9824038801739, 99.6167160401137, 100.872755411671, 100.96954501397, 100.383846665027, 98.1484443369325,
                99.9460032631738, 101.064773214338, 100.813195037412, 99.8091835258957, 97.3000701914363, 100.060966638801,
                100.573751697484, 100.045803579725, 100.157412540176, 100.431565372869, 99.6034502639498, 101.309978225752,
                100.470393399874, 98.7573297294254, 101.381575456386, 101.20445893701, 100.824073963682, 98.3373705978144,
                99.4306936563945, 100.63551381729, 100.043722007578, 100.348012303661, 102.45959354887, 99.1816196756003,
                97.8867998850709, 100.27369527243, 99.3124031587566, 100.446041052962, 99.1876152762094, 102.212055480335,
                99.8762940284226, 99.5226644939699, 99.8337385085134, 100.862563383626, 100.097340485203, 98.3743832607887
            };
            Check(x, 99, 0);
            Check(x, 100, 0.6487);
            Check(x, 101, 1);
        }

        [AssertionMethod]
        private void Check(double[] x, double y, double pvalue)
        {
            var student = StudentTest.Instance.IsGreater(new Statistics(x), y);
            output.WriteLine("PValue         = " + student.PValue);
            output.WriteLine("H0             = " + student.H0);
            output.WriteLine("H1             = " + student.H1);
            output.WriteLine("H0 is rejected = " + student.NullHypothesisIsRejected);
            output.WriteLine("------------");
            Assert.Equal(pvalue, student.PValue, 4);
        }
    }
}