<?php

use Mockery as m;

use EasyRdf\Literal;

class DateStatsControllerTest extends TestCase
{
    private $ES_QUERY;

    public function setUp() {
        parent::setup();
        $this->ES_QUERY = [
            'index' => 'corpus',
            'body' => [
                "size" => 0,
                "query" => [ "match_all" => (object) null ],
                "aggs" => [
                    "datestats" => [
                        "nested"=> [
                            "path" => "creation_years"
                        ],
                        "aggs" => [
                            "years" => [
                                "terms"=> [
                                    "field" => "creation_years.year",
                                    "size" => 2147483647,
                                    "order" => [
                                        "_term" => "asc"
                                    ]
                                ],
                                "aggs" => [
                                    "year_count" => [
                                        "sum" => [
                                            "field" => "creation_years.weight"
                                        ]
                                    ]
                                ]
                            ]
                        ]
                    ]
                ]
            ]
        ];

        $this->ES_QUERY_MINMAX = [
            'index' => 'corpus',
            'body' => [
                "size" => 0,
                "query" => [ "match_all" => (object) null ],
                "aggs" => [
                    "datestats" => [
                        "nested"=> [
                            "path" => "creation_years"
                        ],
                        "aggs" => [
                            "minyear" => [
                                "min" => [ "field"=> "creation_years.year" ]
                            ],
                            "maxyear" => [
                                "max" => [ "field"=> "creation_years.year" ]
                            ]
                        ]
                    ]
                ]
            ]
        ];
    }

    public function tearDown() {
        m::close();
        parent::tearDown();
    }


    public function testIndexQuery() {

        Es::shouldReceive('search')
                ->once()
                ->with($this->ES_QUERY)
                ->andReturn(json_decode('{
                    "took" : 132,
                    "timed_out" : false,
                    "_shards" : {
                        "total" : 1,
                        "successful" : 1,
                        "failed" : 0
                    },
                    "hits" : {
                        "total" : 3373,
                        "max_score" : 0.0,
                        "hits" : [ ]
                    },
                    "aggregations" : {
                        "datestats" : {
                            "doc_count" : 3725,
                            "years" : {
                                "doc_count_error_upper_bound" : 0,
                                "sum_other_doc_count" : 0,
                                "buckets" : []
                            }
                        }
                    }
                }', true));
            $response = $this->get('/api/v1/stats/datestats/');
            $response
                ->assertStatus(200)
                ->assertJson(["datestats" => []]);
    }

    public function testIndexResult() {

        Es::shouldReceive('search')
                ->once()
                ->with($this->ES_QUERY)
                ->andReturn(json_decode('{
                    "took" : 132,
                    "timed_out" : false,
                    "_shards" : {
                        "total" : 1,
                        "successful" : 1,
                        "failed" : 0
                    },
                    "hits" : {
                        "total" : 3373,
                        "max_score" : 0.0,
                        "hits" : [ ]
                    },
                    "aggregations" : {
                        "datestats" : {
                            "doc_count" : 3725,
                            "years" : {
                                "doc_count_error_upper_bound" : 0,
                                "sum_other_doc_count" : 0,
                                "buckets" : [ {
                                    "key" : 1948,
                                    "doc_count" : 3,
                                    "year_count" : { "value" : 3.0 }
                                }, {
                                    "key" : 1957,
                                    "doc_count" : 29,
                                    "year_count" : { "value" : 29.0 }
                                }, {
                                    "key" : 1963,
                                    "doc_count" : 22,
                                    "year_count" : { "value" : 21.5 }
                                },  {
                                    "key" : 1970,
                                    "doc_count" : 411,
                                    "year_count" : { "value" : 403.68333334475756 }
                                },  {
                                    "key" : 1986,
                                    "doc_count" : 68,
                                    "year_count" : { "value" : 14.133333388715982 }
                                }, {
                                    "key" : 1996,
                                    "doc_count" : 40,
                                    "year_count" : { "value" : 36.05000001564622 }
                                } ]
                            }
                        }
                    }
                }', true));
            $response = $this->get('/api/v1/stats/datestats/');
            $response
                ->assertStatus(200)
                ->assertJson(["datestats" => [
                "1948" => 3,
                "1957" => 29,
                "1963" => 22,
                "1970" => 404,
                "1986" => 14,
                "1996" => 36
            ]]);
    }


    public function testMinMaxQuery() {

        Es::shouldReceive('search')
                ->once()
                ->with($this->ES_QUERY_MINMAX)
                ->andReturn(json_decode('{
                    "took" : 708,
                    "timed_out" : false,
                    "_shards" : {
                        "total" : 1,
                        "successful" : 1,
                        "failed" : 0
                    },
                    "hits" : {
                        "total" : 0,
                        "max_score" : 0.0,
                        "hits" : [ ]
                    },
                    "aggregations" : {
                        "datestats" : {
                            "doc_count" : 0,
                            "maxyear" : {
                                "value" : null
                            },
                            "minyear" : {
                                "value" : null
                            }
                        }
                    }
                }', true));
        $response = $this->get('/api/v1/stats/dateminmax/');
        $response
            ->assertStatus(200)
            ->assertJson(["dateminmax" => [0, 0]]);
    }

    public function testMinMaxResult() {

        Es::shouldReceive('search')
                ->once()
                ->with($this->ES_QUERY_MINMAX)
                ->andReturn(json_decode('{
                    "took" : 708,
                    "timed_out" : false,
                    "_shards" : {
                        "total" : 1,
                        "successful" : 1,
                        "failed" : 0
                    },
                    "hits" : {
                        "total" : 3375,
                        "max_score" : 0.0,
                        "hits" : [ ]
                    },
                    "aggregations" : {
                        "datestats" : {
                            "doc_count" : 3727,
                            "maxyear" : {
                                "value" : 2015.0
                            },
                            "minyear" : {
                                "value" : 1948.0
                            }
                        }
                    }
                }', true));
        $response = $this->get('/api/v1/stats/dateminmax/');
        $response
            ->assertStatus(200)
            ->assertJson(["dateminmax" => [ 1948, 2015 ]]);
    }

}
