# -*- coding: utf-8 -*-
"""QGIS Unit tests for QgsServer WMS GetLegendGraphic.

From build dir, run: ctest -R PyQgsServerWMSGetLegendGraphic -V


.. note:: This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.

"""
__author__ = 'Alessandro Pasotti'
__date__ = '25/05/2015'
__copyright__ = 'Copyright 2015, The QGIS Project'

import os

# Needed on Qt 5 so that the serialization of XML is consistent among all executions
os.environ
['QT_HASH_SEED'] = '1'

import re
import urllib.request
import urllib.parse
import urllib.error

from qgis.testing import unittest
from qgis.PyQt.QtCore import QSize

import osgeo.gdal  # NOQA

from test_qgsserver import QgsServerTestBase
from qgis.core import QgsProject

# Strip path and content length because path may vary
RE_STRIP_UNCHECKABLE = b'MAP=[^"]+|Content-Length: \d+'
RE_ATTRIBUTES = b'[^>\s]+=[^>\s]+'


class TestQgsServerWMSGetLegendGraphic(QgsServerTestB
ase):
    """QGIS Server WMS Tests for GetLegendGraphic request"""

    # Set to True to re-generate reference files for this class
    #regenerate_reference = True

    def test_getLegendGraphics(self):
        """Test that does not return an exception but an image"""
        parms = {
            'MAP': self.testdata_path + "test_project.qgs",
            'SERVICE': 'WMS',
            'VERSION': '1.3.0',
            'REQUEST': 'GetLegendGraphic',
            'FORMAT': 'image/png',
            # 'WIDTH': '20', # optional
            # 'HEIGHT': '20', # optional
            'LAYER': 'testlayer%20èé',
        }
        qs = '?' + '&'.join(["%s=%s" % (k, v) for k, v in parms.items()])
        h, r = self._execute_request(qs)
        self.assertEqual(-1, h.find(b'Content-Type: text/xml; charset=utf-8'), "Header: %s\nResponse:\n%s" % (h, r))
        self.assertNotEqual(-1, h.find(b'Content-Type: image/png'), "Header: %s\nResponse:\n%s" % (h, r))

    def test_wms_GetLegendGraphic_LayerSpace(self):
        qs = "?" + "&".join(["%s=%s" % i for i in list({
            "MAP": urllib.parse.quote(self.projectPath),
            "SERVICE": "WMS",
            "VERSION": "1.1.1",
            "REQUEST": "GetLegendGraphic",
            "LAYER": "Country,Hello",
            "FORMAT": "image/png",
            # "HEIGHT": "500",
            # "WIDTH": "500",
            "LAYERSPACE": "50.0",
            "LAYERFONTBOLD": "TRUE",
            "LAYERFONTSIZE": "30",
            "ITEMFONTBOLD": "TRUE",
            "ITEMFONTSIZE": "20",
            "LAYERFONTFAMILY": self.fontFamily,
            "ITEMFONTFAMILY": self.fontFamily,
            "LAYERTITLE": "TRUE",
            "CRS": "EPSG:3857"
        }.items())])

        r, h = self._result(self._execute_request(qs))
        self._img_diff_error(r, h, "WMS_GetLegendGraphic_LayerSpace", max_size_diff=QSize(1, 1))

    def test_wms_getLegendGraphics_invalid_parameters(self):
        """Test that does return an exception"""
        qs = "?" + "&".join(["%s=%s" % i for i in list({
            "MAP": urllib.parse.quote(self.projectPath),
            "SERVICE": "WMS",
            "VERSION": "1.1.1",
            "REQUEST": "GetLegendGraphic",
            "LAYER": "Country,Hello,db_point",
            "LAYERTITLE": "FALSE",
            "FORMAT": "image/png",
            "HEIGHT": "500",
            "WIDTH": "500",
            "RULE": "1",
            "BBOX": "-151.7,-38.9,51.0,78.0",
            "CRS": "EPSG:4326"
        }.items())])

        r, h = self._result(self._execute_request(qs))
        err = b"BBOX parameter cannot be combined with RULE" in r
        self.assertTrue(err)

    def test_wms_GetLegendGraphic_LayerTitleSpace(self):
        qs = "?" + "&".join(["%s=%s" % i for i in list({
            "MAP": urllib.parse.quote(self.projectPath),
            "SERVICE": "WMS",
            "VERSION": "1.1.1",
            "REQUEST": "GetLegendGraphic",
            "LAYER": "Country,Hello",
            "FORMAT": "image/png",
            # "HEIGHT": "500",
            # "WIDTH": "500",
            "LAYERTITLESPACE": "20.0",
            "LAYERFONTBOLD": "TRUE",
            "LAYERFONTSIZE": "30",
            "ITEMFONTBOLD": "TRUE",
            "ITEMFONTSIZE": "20",
            "LAYERFONTFAMILY": self.fontFamily,
            "ITEMFONTFAMILY": self.fontFamily,
            "LAYERTITLE": "TRUE",
            "CRS": "EPSG:3857"
        }.items())])

        r, h = self._result(self._execute_request(qs))
        self._img_diff_error(r, h, "WMS_GetLegendGraphic_LayerTitleSpace")

    def test_wms_GetLegendGraphic_ShowFeatureCount(self):
        qs = "?" + "&".join(["%s=%s" % i for i in list({
            "MAP": urllib.parse.quote(self.projectPath),
            "SERVICE": "WMS",
            "VERSION": "1.1.1",
            "REQUEST": "GetLegendGraphic",
            "LAYER": "Country,Hello",
            "FORMAT": "image/png",
            # "HEIGHT": "500",
            # "WIDTH": "500",
            "LAYERTITLE": "TRUE",
            "LAYERFONTBOLD": "TRUE",
            "LAYERFONTSIZE": "30",
            "LAYERFONTFAMILY": self.fontFamily,
            "ITEMFONTFAMILY": self.fontFamily,
            "ITEMFONTBOLD": "TRUE",
            "ITEMFONTSIZE": "20",
            "SHOWFEATURECOUNT": "TRUE",
            "CRS": "EPSG:3857"
        }.items())])

        r, h = self._result(self._execute_request(qs))
        self._img_diff_error(r, h, "WMS_GetLegendGraphic_ShowFeatureCount", max_size_diff=QSize(1, 1))

    def test_wms_getLegendGraphics_layertitle(self):
        """Test that does not return an exception but an image"""

        print("TEST FONT FAMILY: ", self.fontFamily)

        parms = {
            'MAP': self.testdata_path + "test_project.qgs",
            'SERVICE': 'WMS',
            'VERSION': '1.3.0',
            'REQUEST': 'GetLegendGraphic',
            'FORMAT': 'image/png',
            # 'WIDTH': '20', # optional
            # 'HEIGHT': '20', # optional
            'LAYER': u'testlayer%20èé',
            'LAYERFONTBOLD': 'TRUE',
            'LAYERFONTSIZE': '30',
            'ITEMFONTBOLD': 'TRUE',
            'LAYERFONTFAMILY': self.fontFamily,
            'ITEMFONTFAMILY': self.fontFamily,
            'ITEMFONTSIZE': '20',
            'LAYERTITLE': 'TRUE',
        }
        qs = '?' + '&'.join([u"%s=%s" % (k, v) for k, v in parms.items()])
        r, h = self._result(self._execute_request(qs))
        self._img_diff_error(r, h, "WMS_GetLegendGraphic_test", 250, QSize(15, 15))

        parms = {
            'MAP': self.testdata_path + "test_project.qgs",
            'SERVICE': 'WMS',
            'VERSION': '1.3.0',
            'REQUEST': 'GetLegendGraphic',
            'FORMAT': 'image/png',
            # 'WIDTH': '20', # optional
            # 'HEIGHT': '20', # optional
            'LAYER': u'testlayer%20èé',
            'LAYERTITLE': 'FALSE',
        }
        qs = '?' + '&'.join([u"%s=%s" % (k, v) for k, v in parms.items()])
        r, h = self._result(self._execute_request(qs))
        self._img_diff_error(r, h, "WMS_GetLegendGraphic_test_layertitle_false", 250, QSize(15, 15))

    def test_wms_getLegendGraphics_rulelabel(self):
        """Test that does not return an exception but an image"""
        parms = {
            'MAP': self.testdata_path + "test_project.qgs",
            'SERVICE': 'WMS',
            'VERSION': '1.3.0',
            'REQUEST': 'GetLegendGraphic',
            'FORMAT': 'image/png',
            'LAYER': u'testlayer%20èé',
            'LAYERFONTBOLD': 'TRUE',
            'LAYERFONTSIZE': '30',
            'LAYERFONTFAMILY': self.fontFamily,
            'ITEMFONTFAMILY': self.fontFamily,
            'ITEMFONTBOLD': 'TRUE',
            'ITEMFONTSIZE': '20',
            'RULELABEL': 'TRUE',
        }
        qs = '?' + '&'.join([u"%s=%s" % (k, v) for k, v in parms.items()])
        r, h = self._result(self._execute_request(qs))
        self._img_diff_error(r, h, "WMS_GetLegendGraphic_test", 250, QSize(15, 15))

        parms = {
            'MAP': self.testdata_path + "test_project.qgs",
            'SERVICE': 'WMS