"""test distributed temporal databases with str3ds

(C) 2014 by the GRASS Development Team
This program is free software under the GNU General Public
License (>=v2). Read the file COPYING that comes with GRASS
for details.

:authors: Soeren Gebbert
"""

from grass.gunittest.case import TestCase
from grass.gunittest.gmodules import SimpleModule
from grass.gunittest.utils import silent_rmtree
import os


class testRaster3dExtraction(TestCase):
    mapsets_to_remove = []
    outfile = "rast3dlist.txt"
    gisenv = SimpleModule("g.gisenv", get="MAPSET")
    TestCase.runModule(gisenv, expecting_stdout=True)
    old_mapset = gisenv.outputs.stdout.strip()

    @classmethod
    def setUpClass(cls):
        os.putenv("GRASS_OVERWRITE", "1")
        for i in range(1, 5):
            mapset_name = "test3d%i" % i
            cls.runModule("g.mapset", flags="c", mapset=mapset_name)
            cls.mapsets_to_remove.append(mapset_name)
            cls.runModule("g.region", s=0, n=80, w=0, e=120, b=0, t=50, res=10, res3=10)
            # Use always the current mapset as temporal database
            cls.runModule("r3.mapcalc", expression="a1 = 100")
            cls.runModule("r3.mapcalc", expression="a2 = 200")
            cls.runModule("r3.mapcalc", expression="a3 = 300")
            # Create the temporal database
            cls.runModule("t.connect", flags="d")
            cls.runModule("t.info", flags="d")
            cls.runModule(
                "t.create",
                type="str3ds",
                temporaltype="absolute",
                output="A",
                title="A test3d",
                description="A test3d",
            )
            cls.runModule(
                "t.register",
                flags="i",
                type="raster_3d",
                input="A",
                maps="a1,a2,a3",
                start="2001-01-01",
                increment="%i months" % i,
            )

        # Add the new mapsets to the search path
        for mapset in cls.mapsets_to_remove:
            cls.runModule("g.mapset", mapset=mapset)
            cls.runModule(
                "g.mapsets", operation="add", mapset=",".join(cls.mapsets_to_remove)
            )

    @classmethod
    def tearDownClass(cls):
        gisenv = SimpleModule("g.gisenv", get="GISDBASE")
        cls.runModule(gisenv, expecting_stdout=True)
        gisdbase = gisenv.outputs.stdout.strip()
        gisenv = SimpleModule("g.gisenv", get="LOCATION_NAME")
        cls.runModule(gisenv, expecting_stdout=True)
        location = gisenv.outputs.stdout.strip()
        cls.runModule("g.mapset", mapset=cls.old_mapset)
        for mapset_name in cls.mapsets_to_remove:
            mapset_path = os.path.join(gisdbase, location, mapset_name)
            silent_rmtree(mapset_path)

    def test_tlist(self):
        self.runModule("g.mapset", mapset="test3d1")

        list_string = """A|test3d1|2001-01-01 00:00:00|2001-04-01 00:00:00|3
                                A|test3d2|2001-01-01 00:00:00|2001-07-01 00:00:00|3
                                A|test3d3|2001-01-01 00:00:00|2001-10-01 00:00:00|3
                                A|test3d4|2001-01-01 00:00:00|2002-01-01 00:00:00|3"""

        t_list = SimpleModule(
            "t.list",
            quiet=True,
            columns=["name", "mapset,start_time", "end_time", "number_of_maps"],
            type="str3ds",
            where='name = "A"',
        )
        self.assertModule(t_list)

        out = t_list.outputs["stdout"].value

        for a, b in zip(list_string.split("\n"), out.split("\n")):
            self.assertEqual(a.strip(), b.strip())

        t_list = SimpleModule(
            "t.list",
            quiet=True,
            columns=["name", "mapset,start_time", "end_time", "number_of_maps"],
            type="str3ds",
            where='name = "A"',
            output=self.outfile,
        )
        self.assertModule(t_list)
        self.assertFileExists(self.outfile)
        with open(self.outfile, "r") as f:
            read_data = f.read()
        for a, b in zip(list_string.split("\n"), read_data.split("\n")):
            self.assertEqual(a.strip(), b.strip())
        # self.assertLooksLike(reference=read_data, actual=list_string)
        if os.path.isfile(self.outfile):
            os.remove(self.outfile)

    def test_trast_list(self):
        self.runModule("g.mapset", mapset="test3d1")

        list_string = """a1|test3d1|2001-01-01 00:00:00|2001-02-01 00:00:00
                                a2|test3d1|2001-02-01 00:00:00|2001-03-01 00:00:00
                                a3|test3d1|2001-03-01 00:00:00|2001-04-01 00:00:00"""

        trast_list = SimpleModule(
            "t.rast3d.list", quiet=True, flags="s", input="A@test3d1"
        )
        self.assertModule(trast_list)

        out = trast_list.outputs["stdout"].value

        for a, b in zip(list_string.split("\n"), out.split("\n")):
            self.assertEqual(a.strip(), b.strip())

        list_string = """a1|test3d2|2001-01-01 00:00:00|2001-03-01 00:00:00
                                a2|test3d2|2001-03-01 00:00:00|2001-05-01 00:00:00
                                a3|test3d2|2001-05-01 00:00:00|2001-07-01 00:00:00"""

        trast_list = SimpleModule(
            "t.rast3d.list", quiet=True, flags="s", input="A@test3d2"
        )
        self.assertModule(trast_list)

        out = trast_list.outputs["stdout"].value

        for a, b in zip(list_string.split("\n"), out.split("\n")):
            self.assertEqual(a.strip(), b.strip())

        list_string = """a1|test3d3|2001-01-01 00:00:00|2001-04-01 00:00:00
                                a2|test3d3|2001-04-01 00:00:00|2001-07-01 00:00:00
                                a3|test3d3|2001-07-01 00:00:00|2001-10-01 00:00:00"""

        trast_list = SimpleModule(
            "t.rast3d.list", quiet=True, flags="s", input="A@test3d3"
        )
        self.assertModule(trast_list)

        out = trast_list.outputs["stdout"].value

        for a, b in zip(list_string.split("\n"), out.split("\n")):
            self.assertEqual(a.strip(), b.strip())

        list_string = """a1|test3d4|2001-01-01 00:00:00|2001-05-01 00:00:00
                                a2|test3d4|2001-05-01 00:00:00|2001-09-01 00:00:00
                                a3|test3d4|2001-09-01 00:00:00|2002-01-01 00:00:00"""

        trast_list = SimpleModule(
            "t.rast3d.list", quiet=True, flags="s", input="A@test3d4"
        )
        self.assertModule(trast_list)

        out = trast_list.outputs["stdout"].value

        for a, b in zip(list_string.split("\n"), out.split("\n")):
            self.assertEqual(a.strip(), b.strip())

        trast_list = SimpleModule(
            "t.rast3d.list",
            quiet=True,
            flags="s",
            input="A@test3d4",
            output=self.outfile,
        )
        self.assertModule(trast_list)
        self.assertFileExists(self.outfile)
        with open(self.outfile, "r") as f:
            read_data = f.read()
        for a, b in zip(list_string.split("\n"), read_data.split("\n")):
            self.assertEqual(a.strip(), b.strip())
        if os.path.isfile(self.outfile):
            os.remove(self.outfile)

    def test_strds_info(self):
        self.runModule("g.mapset", mapset="test3d4")
        tinfo_string = """id=A@test3d1
                                    name=A
                                    mapset=test3d1
                                    start_time='2001-01-01 00:00:00'
                                    end_time='2001-04-01 00:00:00'
                                    granularity='1 month'"""

        info = SimpleModule("t.info", flags="g", type="str3ds", input="A@test3d1")
        self.assertModuleKeyValue(
            module=info, reference=tinfo_string, precision=2, sep="="
        )

        self.runModule("g.mapset", mapset="test3d3")
        tinfo_string = """id=A@test3d2
                                    name=A
                                    mapset=test3d2
                                    start_time='2001-01-01 00:00:00'
                                    end_time='2001-07-01 00:00:00'
                                    granularity='2 months'"""

        info = SimpleModule("t.info", flags="g", type="str3ds", input="A@test3d2")
        self.assertModuleKeyValue(
            module=info, reference=tinfo_string, precision=2, sep="="
        )

        self.runModule("g.mapset", mapset="test3d2")
        tinfo_string = """id=A@test3d3
                                    name=A
                                    mapset=test3d3
                                    start_time='2001-01-01 00:00:00'
                                    end_time='2001-10-01 00:00:00'
                                    granularity='3 months'"""

        info = SimpleModule("t.info", flags="g", type="str3ds", input="A@test3d3")
        self.assertModuleKeyValue(
            module=info, reference=tinfo_string, precision=2, sep="="
        )

        self.runModule("g.mapset", mapset="test3d1")
        tinfo_string = """id=A@test3d4
                                    name=A
                                    mapset=test3d4
                                    start_time='2001-01-01 00:00:00'
                                    end_time='2002-01-01 00:00:00'
                                    granularity='4 months'"""

        info = SimpleModule("t.info", flags="g", type="str3ds", input="A@test3d4")
        self.assertModuleKeyValue(
            module=info, reference=tinfo_string, precision=2, sep="="
        )

    def test_raster_info(self):
        self.runModule("g.mapset", mapset="test3d3")
        tinfo_string = """id=a1@test3d1
                                name=a1
                                mapset=test3d1
                                temporal_type=absolute
                                start_time='2001-01-01 00:00:00'
                                end_time='2001-02-01 00:00:00'"""

        info = SimpleModule("t.info", flags="g", type="raster_3d", input="a1@test3d1")
        self.assertModuleKeyValue(
            module=info, reference=tinfo_string, precision=2, sep="="
        )

        tinfo_string = """id=a1@test3d2
                                name=a1
                                mapset=test3d2
                                temporal_type=absolute
                                start_time='2001-01-01 00:00:00'
                                end_time='2001-03-01 00:00:00'"""

        info = SimpleModule("t.info", flags="g", type="raster_3d", input="a1@test3d2")
        self.assertModuleKeyValue(
            module=info, reference=tinfo_string, precision=2, sep="="
        )

        tinfo_string = """id=a1@test3d3
                                name=a1
                                mapset=test3d3
                                temporal_type=absolute
                                start_time='2001-01-01 00:00:00'
                                end_time='2001-04-01 00:00:00'"""

        info = SimpleModule("t.info", flags="g", type="raster_3d", input="a1@test3d3")
        self.assertModuleKeyValue(
            module=info, reference=tinfo_string, precision=2, sep="="
        )

        tinfo_string = """id=a1@test3d4
                                name=a1
                                mapset=test3d4
                                temporal_type=absolute
                                start_time='2001-01-01 00:00:00'
                                end_time='2001-05-01 00:00:00'"""

        info = SimpleModule("t.info", flags="g", type="raster_3d", input="a1@test3d4")
        self.assertModuleKeyValue(
            module=info, reference=tinfo_string, precision=2, sep="="
        )


if __name__ == "__main__":
    from grass.gunittest.main import test

    test()
