#!/usr/bin/env python3

import json
import re
import os
import pathlib
import shutil
import subprocess
import sys

import pytest


SCRIPT_ROOT = pathlib.Path(__file__).resolve().parent
BR2_ROOT = (SCRIPT_ROOT / '../../').resolve()

INSTALL_SCRIPT_PATH = BR2_ROOT / 'package/czechlight-cfg-fs/czechlight-install-yang.sh'
MIGRATE_SCRIPT_PATH = BR2_ROOT / 'package/czechlight-cfg-fs/czechlight-migrate.sh'
MIGRATE_DEFINITIONS_PATH = BR2_ROOT / 'package/czechlight-cfg-fs/czechlight-migration-list.sh'
NETOPEER_SCRIPT_PATH = BR2_ROOT / 'submodules/buildroot/package/netopeer2/setup.sh'

CLA_SYSREPO_PATH = BR2_ROOT / 'submodules/cla-sysrepo'
VELIA_PATH = BR2_ROOT / 'submodules/velia'
ROUSETTE_PATH = BR2_ROOT / 'submodules/rousette'
ALARMS_PATH = BR2_ROOT / 'submodules/sysrepo-ietf-alarms'
NETOPEER2_PATH = BR2_ROOT / 'submodules/dependencies/Netopeer2'


def run_and_wait(ctx, desc, command_args):
    print(f'executing {desc}')
    with subprocess.Popen(command_args, stdout=sys.stdout, stderr=sys.stderr, env=ctx.get_env()) as proc:
        proc.wait()
        assert proc.returncode == 0


class SysrepoFixture:
    def __init__(self, test_directory, tmp_path):
        test_directory = SCRIPT_ROOT / test_directory
        self.test_name = test_directory.name

        self.expected_file = test_directory / 'expected.json'
        assert self.expected_file.is_file()

        startup = test_directory / 'startup.json'
        assert startup.is_file()

        self.proc_cmdline = test_directory / 'cmdline'
        assert self.proc_cmdline.is_file()

        version_file = test_directory / 'version'
        assert version_file.is_file()

        tested_xpath_file = test_directory / 'xpath'
        self.tested_xpath = tested_xpath_file.read_text() if tested_xpath_file.is_file() else None

        self._running_directory = tmp_path / self.test_name
        self._running_directory.mkdir()

        self.startup_file = self._running_directory / 'startup.json'
        shutil.copyfile(startup, self.startup_file)

        self.export_file = self._running_directory / 'export.json'

        self.version_file = self._running_directory / 'version'
        shutil.copy(version_file, self.version_file)

    def get_env(self):
        res = os.environ.copy()
        res['SYSREPO_SHM_PREFIX'] = self.test_name
        res['SYSREPO_REPOSITORY_PATH'] = self._running_directory / 'sysrepo_repository'
        res['CLA_YANG'] = CLA_SYSREPO_PATH / 'yang'
        res['VELIA_YANG'] = VELIA_PATH / 'yang'
        res['ROUSETTE_YANG'] = ROUSETTE_PATH / 'yang'
        res['ALARMS_YANG'] = ALARMS_PATH / 'yang'
        res['PROC_CMDLINE'] = self.proc_cmdline
        res['CFG_VERSION_FILE'] = self.version_file
        res['CFG_STARTUP_FILE'] = self.startup_file
        res['NP2_MODULE_DIR'] = NETOPEER2_PATH / 'modules'
        res['NP2_MODULE_PERMS'] = '0600'
        res['USER'] = os.getlogin()
        return res


@pytest.fixture(scope='session')
def max_version():
    """
    Fetches last version from czechlight-migrate script by sourcing the
    migration definitions file and verifying the length of the migration
    files array.
    """
    args = ["/bin/bash", "-c", "source " + str(MIGRATE_DEFINITIONS_PATH) + " && echo ${#MIGRATION_FILES[@]}"]
    with subprocess.Popen(args, stdout=subprocess.PIPE, stderr=subprocess.PIPE) as proc:
        proc.wait()
        stdout, stderr = proc.communicate()
        assert stderr.decode().strip() == ''
        assert proc.returncode == 0

    return int(stdout.decode().strip())


@pytest.fixture
def sysrepo_fixture(request, tmp_path):
    return SysrepoFixture(pathlib.Path(SCRIPT_ROOT / 'data' / request.param), tmp_path)


def find_test_directories():
    return [pytest.param(dirname) for dirname in os.listdir(path=SCRIPT_ROOT / 'data')]


@pytest.mark.parametrize("sysrepo_fixture", find_test_directories(), indirect=True)
def test(sysrepo_fixture, max_version):
    # prepare sysrepo
    run_and_wait(sysrepo_fixture, 'netopeer2 setup.sh', [NETOPEER_SCRIPT_PATH])
    run_and_wait(sysrepo_fixture, 'czechlight-install-yang.sh', [INSTALL_SCRIPT_PATH])
    run_and_wait(sysrepo_fixture, 'restoring startup.json to sysrepo', ['sysrepocfg', '--datastore', 'startup', '--format', 'json', f'--import={sysrepo_fixture.startup_file}'])

    current_version = int(sysrepo_fixture.version_file.read_text())

    # perform the actual migration
    print(f'migration: current version is {current_version}')
    print('migration: applying migration script')
    run_and_wait(sysrepo_fixture, 'migration', [MIGRATE_SCRIPT_PATH])

    after_migration_version = int(sysrepo_fixture.version_file.read_text())
    assert after_migration_version == max_version

    print('migration: checking datastore contents')
    export_args = ['sysrepocfg', '--datastore', 'startup', '-f', 'json', f'--export={sysrepo_fixture.export_file}']
    if sysrepo_fixture.tested_xpath:
        export_args += ['-x', sysrepo_fixture.tested_xpath]
    run_and_wait(sysrepo_fixture, 'export', export_args)

    with open(sysrepo_fixture.export_file, 'r') as fp_actual:
        with open(sysrepo_fixture.expected_file, 'r') as fp_expected:
            print(f'migration: comparing files {sysrepo_fixture.export_file.name} and {sysrepo_fixture.expected_file.name}')

            actual = json.load(fp_actual)
            expected = json.load(fp_expected)
            assert actual == expected
