## SPDX-License-Identifier: BSD-2-Clause
##
## Copyright 2020-2025 Inria & Université de Bordeaux
##
## Redistribution and use in source and binary forms, with or without
## modification, are permitted provided that the following conditions
## are met:
##
## 1. Redistributions of source code must retain the above copyright
## notice, this list of conditions and the following disclaimer.
##
## 2. Redistributions in binary form must reproduce the above
## copyright notice, this list of conditions and the following
## disclaimer in the documentation and/or other materials provided
## with the distribution.
##
## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
## CONTRIBUTORS “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES,
## INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
## MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
## DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS
## BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
## TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
## DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
## ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
## TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
## THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
## SUCH DAMAGE.
##

import scotchpy as SCOTCH
import tempfile
import os
import importlib.resources

_data_dir = importlib.resources.files('scotchpy').joinpath("data")
# taken from check/test_scotch_arch.c


def testMain():
    # Due to the inter-depending nature of these tests, they are all in the same method.
    vnumtab = [0, 4, 1, 5, 7, 11, 13, 15]
    dimntab = [3, 3, 5, 4, 8]
    sizetab = [6, 3, 4]
    linktab = [20, 5, 1]
    archtab = [SCOTCH.Arch() for _ in range(20)]

    archnbr = 0

    try:
        archtab[archnbr].hcub(4)
    except SCOTCH.LibraryError:
        assert False, "cannot create hcub architecture"
        raise
    archnbr += 1

    try:
        archtab[archnbr].cmplt(8)
    except SCOTCH.LibraryError:
        assert False, "cannot create cmplt architecture"
        raise
    archnbr += 1

    try:
        archtab[archnbr].mesh2(2, 4)
    except SCOTCH.LibraryError:
        assert False, "cannot create mesh2D architecture"
        raise
    archnbr += 1

    try:
        archtab[archnbr].mesh3(3, 4, 5)
    except SCOTCH.LibraryError:
        assert False, "cannot create mesh3D architecture"
        raise
    archnbr += 1

    try:
        archtab[archnbr].meshX(dimntab)
    except SCOTCH.LibraryError:
        assert False, "cannot create meshXD architecture"
        raise
    archnbr += 1

    try:
        archtab[archnbr].tleaf(sizetab, linktab)
    except SCOTCH.LibraryError:
        assert False, "cannot create tleaf architecture"
        raise
    archnbr += 1

    try:
        archtab[archnbr].torus2(2, 4)
    except SCOTCH.LibraryError:
        assert False, "cannot create torus2D architecture"
        raise
    archnbr += 1

    try:
        archtab[archnbr].torus3(3, 4, 5)
    except SCOTCH.LibraryError:
        assert False, "cannot create torus3D architecture"
        raise
    archnbr += 1

    try:
        archtab[archnbr].torusX(dimntab)
    except SCOTCH.LibraryError:
        assert False, "cannot create torusXD architecture"
        raise
    archnbr += 1

    try:
        archtab[archnbr].sub(archtab[0], vnumtab)
    except SCOTCH.LibraryError:
        assert False, "cannot create sub-architecture (1)"
        raise
    archnbr += 1

    for i in range(archnbr):
        try:
            archtab[i + archnbr].sub(archtab[i], vnumtab[:5])
        except SCOTCH.LibraryError:
            assert False, "cannot create sub-architecture ({})".format(2 + i)
            raise
    archnbr *= 2

    with tempfile.TemporaryDirectory() as tmpdirname:
        filename = os.path.join(tmpdirname, "test_scotchpy_arch_output.txt")
        for i in range(archnbr):
            try:
                archtab[i].save(filename)
            except SCOTCH.LibraryError:
                assert False, "cannot save architecture ({})".format(i + 1)
                raise

        for i in range(archnbr - 1, -1, -1):
            archtab[i].exit()

        for i in range(archnbr):
            try:
                archtab[i].init()
                archtab[i].load(filename)
            except SCOTCH.LibraryError:
                assert False, "cannot load architecture ({})".format(i + 1)
                raise

        for i in range(archnbr):
            archtab[i].exit()


# taken from check/test_scotch_arch_deco.c


def testDeco():
    archtab = [SCOTCH.Arch() for _ in range(6)]
    listtab = [0, 4, 1, 5, 7]
    filename1 = os.path.join(_data_dir, "m4x4.grf")
    tmpdir = tempfile.TemporaryDirectory()
    filename2 = os.path.join(tmpdir.name, "test_scotchpy_arch_deco_output.txt")

    try:
        graf = SCOTCH.Graph()
    except SCOTCH.LibraryError:
        assert False, "cannot initialize graph"
        raise

    try:
        graf.load(filename1, -1, 0)
    except SCOTCH.LibraryError:
        assert False, "cannot load graph"
        raise

    vertnbr, _ = graf.size(as_dict=False)
    assert vertnbr > 8

    strat = SCOTCH.Strat()

    archnbr = 0
    for i in range(2):
        try:
            if not i:
                archtab[archnbr].build0(graf, [], strat)
            else:
                archtab[archnbr].build2(graf, [])
        except SCOTCH.LibraryError:
            assert (
                False
            ), "cannot create decomposition-described architecture ({})".format(
                2 * i + 1
            )
            raise

        try:
            if not i:
                archtab[archnbr + 1].build0(graf, listtab, strat)
            else:
                archtab[archnbr + 1].build2(graf, listtab)
        except SCOTCH.LibraryError:
            assert (
                False
            ), "cannot create decomposition-described architecture ({})".format(
                2 * i + 2
            )
            raise

        if i:
            try:
                archtab[archnbr + 2].sub(archtab[archnbr], listtab)
            except SCOTCH.LibraryError:
                assert False, "cannot create sub-architecture ({})".format(i + 1)
                raise

        for j in range(i + 2):
            try:
                archtab[archnbr + j].save(filename2)
            except SCOTCH.LibraryError:
                assert False, "cannot save architecture ({})".format(archnbr + j + 1)
                raise

        archnbr += i + 2

    strat.exit()

    for i in range(archnbr - 1, -1, -1):
        archtab[i].exit()

    graf.exit()

    for i in range(archnbr):
        try:
            archtab[i].init()
            archtab[i].load(filename2)
        except SCOTCH.LibraryError:
            assert False, "cannot load architacture ({})".format(i + 1)
            raise

    for i in range(archnbr):
        archtab[i].exit()
    tmpdir.cleanup()
