# -:- encoding: utf-8 -:-
# This file is part of the MapProxy project.
# Copyright (C) 2013 Omniscale <http://omniscale.de>
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#    http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.


import os
import shutil
import tempfile

import yaml

from mapproxy.script.conf.app import config_command
from mapproxy.test.helper import capture


def filename(name):
    return os.path.join(os.path.dirname(__file__), "fixture", name)


class TestMapProxyConfCmd(object):

    def setup(self):
        self.dir = tempfile.mkdtemp()

    def teardown(self):
        if os.path.exists(self.dir):
            shutil.rmtree(self.dir)

    def tmp_filename(self, name):
        return os.path.join(self.dir, name)

    def test_cmd_no_args(self):
        with capture() as (stdout, stderr):
            assert config_command(["mapproxy-conf"]) == 2

        assert "--capabilities required" in stderr.getvalue()

    def test_stdout_output(self):
        with capture(bytes=True) as (stdout, stderr):
            assert (
                config_command(
                    [
                        "mapproxy-conf",
                        "--capabilities",
                        filename("util-conf-wms-111-cap.xml"),
                    ]
                )
                == 0
            )

        assert stdout.getvalue().startswith(b"# MapProxy configuration")

    def test_test_cap_output_no_base(self):
        with capture(bytes=True) as (stdout, stderr):
            assert (
                config_command(
                    [
                        "mapproxy-conf",
                        "--capabilities",
                        filename("util-conf-wms-111-cap.xml"),
                        "--output",
                        self.tmp_filename("mapproxy.yaml"),
                    ]
                )
                == 0
            )

        with open(self.tmp_filename("mapproxy.yaml"), "rb") as f:
            conf = yaml.safe_load(f)

            assert "grids" not in conf
            assert conf["sources"] == {
                "osm_roads_wms": {
                    "supported_srs": [
                        "CRS:84",
                        "EPSG:25831",
                        "EPSG:25832",
                        "EPSG:25833",
                        "EPSG:31466",
                        "EPSG:31467",
                        "EPSG:31468",
                        "EPSG:3857",
                        "EPSG:4258",
                        "EPSG:4326",
                        "EPSG:900913",
                    ],
                    "req": {
                        "layers": "osm_roads",
                        "url": "http://osm.omniscale.net/proxy/service?",
                        "transparent": True,
                    },
                    "type": "wms",
                    "coverage": {
                        "srs": "EPSG:4326",
                        "bbox": [-180.0, -85.0511287798, 180.0, 85.0511287798],
                    },
                },
                "osm_wms": {
                    "supported_srs": [
                        "CRS:84",
                        "EPSG:25831",
                        "EPSG:25832",
                        "EPSG:25833",
                        "EPSG:31466",
                        "EPSG:31467",
                        "EPSG:31468",
                        "EPSG:3857",
                        "EPSG:4258",
                        "EPSG:4326",
                        "EPSG:900913",
                    ],
                    "req": {
                        "layers": "osm",
                        "url": "http://osm.omniscale.net/proxy/service?",
                        "transparent": True,
                    },
                    "type": "wms",
                    "coverage": {
                        "srs": "EPSG:4326",
                        "bbox": [-180.0, -85.0511287798, 180.0, 85.0511287798],
                    },
                },
            }

            assert conf["layers"] == [
                {
                    "title": "Omniscale OpenStreetMap WMS",
                    "layers": [
                        {
                            "name": "osm",
                            "title": "OpenStreetMap (complete map)",
                            "sources": ["osm_wms"],
                        },
                        {
                            "name": "osm_roads",
                            "title": "OpenStreetMap (streets only)",
                            "sources": ["osm_roads_wms"],
                        },
                    ],
                }
            ]
            assert len(conf["layers"][0]["layers"]) == 2

    def test_test_cap_output(self):
        with capture(bytes=True) as (stdout, stderr):
            assert (
                config_command(
                    [
                        "mapproxy-conf",
                        "--capabilities",
                        filename("util-conf-wms-111-cap.xml"),
                        "--output",
                        self.tmp_filename("mapproxy.yaml"),
                        "--base",
                        filename("util-conf-base-grids.yaml"),
                    ]
                )
                == 0
            )

        with open(self.tmp_filename("mapproxy.yaml"), "rb") as f:
            conf = yaml.safe_load(f)

            assert "grids" not in conf
            assert len(conf["sources"]) == 2

            assert conf["caches"] == {
                "osm_cache": {
                    "grids": ["webmercator", "geodetic"],
                    "sources": ["osm_wms"],
                },
                "osm_roads_cache": {
                    "grids": ["webmercator", "geodetic"],
                    "sources": ["osm_roads_wms"],
                },
            }

            assert conf["layers"] == [
                {
                    "title": "Omniscale OpenStreetMap WMS",
                    "layers": [
                        {
                            "name": "osm",
                            "title": "OpenStreetMap (complete map)",
                            "sources": ["osm_cache"],
                        },
                        {
                            "name": "osm_roads",
                            "title": "OpenStreetMap (streets only)",
                            "sources": ["osm_roads_cache"],
                        },
                    ],
                }
            ]
            assert len(conf["layers"][0]["layers"]) == 2

    def test_overwrites(self):
        with capture(bytes=True) as (stdout, stderr):
            assert (
                config_command(
                    [
                        "mapproxy-conf",
                        "--capabilities",
                        filename("util-conf-wms-111-cap.xml"),
                        "--output",
                        self.tmp_filename("mapproxy.yaml"),
                        "--overwrite",
                        filename("util-conf-overwrite.yaml"),
                        "--base",
                        filename("util-conf-base-grids.yaml"),
                    ]
                )
                == 0
            )

        with open(self.tmp_filename("mapproxy.yaml"), "rb") as f:
            conf = yaml.safe_load(f)

            assert "grids" not in conf
            assert len(conf["sources"]) == 2

            assert conf["sources"] == {
                "osm_roads_wms": {
                    "supported_srs": ["EPSG:3857"],
                    "req": {
                        "layers": "osm_roads",
                        "url": "http://osm.omniscale.net/proxy/service?",
                        "transparent": True,
                        "param": 42,
                    },
                    "type": "wms",
                    "coverage": {"srs": "EPSG:4326", "bbox": [0, 0, 90, 90]},
                },
                "osm_wms": {
                    "supported_srs": [
                        "CRS:84",
                        "EPSG:25831",
                        "EPSG:25832",
                        "EPSG:25833",
                        "EPSG:31466",
                        "EPSG:31467",
                        "EPSG:31468",
                        "EPSG:3857",
                        "EPSG:4258",
                        "EPSG:4326",
                        "EPSG:900913",
                    ],
                    "req": {
                        "layers": "osm",
                        "url": "http://osm.omniscale.net/proxy/service?",
                        "transparent": True,
                        "param": 42,
                    },
                    "type": "wms",
                    "coverage": {
                        "srs": "EPSG:4326",
                        "bbox": [-180.0, -85.0511287798, 180.0, 85.0511287798],
                    },
                },
            }

            assert conf["caches"] == {
                "osm_cache": {
                    "grids": ["webmercator", "geodetic"],
                    "sources": ["osm_wms"],
                    "cache": {"type": "sqlite"},
                },
                "osm_roads_cache": {
                    "grids": ["webmercator"],
                    "sources": ["osm_roads_wms"],
                    "cache": {"type": "sqlite"},
                },
            }

            assert conf["layers"] == [
                {
                    "title": "Omniscale OpenStreetMap WMS",
                    "layers": [
                        {
                            "name": "osm",
                            "title": "OpenStreetMap (complete map)",
                            "sources": ["osm_cache"],
                        },
                        {
                            "name": "osm_roads",
                            "title": "OpenStreetMap (streets only)",
                            "sources": ["osm_roads_cache"],
                        },
                    ],
                }
            ]
            assert len(conf["layers"][0]["layers"]) == 2
