<reponame>kthy/wren
# -*- coding: utf-8 -*-
"""Gettext manipulation methods."""

from os import remove
from os.path import exists
from pathlib import Path
from shutil import copyfile, copystat
from typing import Sequence

from filehash import FileHash
from polib import MOFile, POFile, mofile

from wren.change import Change


def apply_changes(mo_file: MOFile, changelist: Sequence[Change]) -> None:
    """Apply all changes in the provided list of changes to the given MOFile."""
    for change in changelist:
        change.apply(mo_file)


def backup_original_mo(wowsdir: str, locale: str) -> None:
    """Copy the original `global.mo` to `global.mo.original`."""
    global_mo_path = _global_mo_path(wowsdir, locale)
    backup_mo_path = _backup_mo_path(wowsdir, locale)
    _copyfile_and_checksum(global_mo_path, backup_mo_path)


def convert_mo_to_po(wowsdir: str, locale: str, outputdir: str) -> POFile:
    """Save the MO file for the given locale in PO format."""
    mofile_path = Path(_global_mo_path(wowsdir, locale))
    if not exists(mofile_path):
        raise OSError(f"MO file for locale {locale} not found")
    mof = mofile(mofile_path)
    mof.save_as_pofile(f"{outputdir}/{mofile_path.stem}_{locale}.po")


def get_mo(wowsdir: str, locale: str) -> MOFile:
    """Open and return the global MO file in the given directory."""
    return mofile(_global_mo_path(wowsdir, locale))


def restore_original_mo(wowsdir: str, locale: str) -> None:
    """Reinstate the original `global.mo` from `global.mo.original`."""
    global_mo_path = _global_mo_path(wowsdir, locale)
    backup_mo_path = _backup_mo_path(wowsdir, locale)
    if exists(backup_mo_path):
        _copyfile_and_checksum(backup_mo_path, global_mo_path)
        remove(backup_mo_path)


def _copyfile_and_checksum(from_path, to_path) -> None:
    """Copy a file from from_path to to_path.

    Raises OSError if the new file's checksum doesn't match the original."""
    copyfile(from_path, to_path)
    copystat(from_path, to_path)
    hasher = FileHash("md5")
    if hasher.hash_file(from_path) != hasher.hash_file(to_path):
        raise OSError("Copy failed, hash mismatch detected")


def _backup_mo_path(wowsdir: str, locale: str) -> str:
    return f"{_global_mo_path(wowsdir, locale)}.original"


def _global_mo_path(wowsdir: str, locale: str) -> str:
    return f"{wowsdir}/res/texts/{locale}/LC_MESSAGES/global.mo"

# -*- coding: utf-8 -*-
"""Gettext manipulation methods."""

from os import remove
from os.path import exists
from pathlib import Path
from shutil import copyfile, copystat
from typing import Sequence

from filehash import FileHash
from polib import MOFile, POFile, mofile

from wren.change import Change


def apply_changes(mo_file: MOFile, changelist: Sequence[Change]) -> None:
    """Apply all changes in the provided list of changes to the given MOFile."""
    for change in changelist:
        change.apply(mo_file)


def backup_original_mo(wowsdir: str, locale: str) -> None:
    """Copy the original `global.mo` to `global.mo.original`."""
    global_mo_path = _global_mo_path(wowsdir, locale)
    backup_mo_path = _backup_mo_path(wowsdir, locale)
    _copyfile_and_checksum(global_mo_path, backup_mo_path)


def convert_mo_to_po(wowsdir: str, locale: str, outputdir: str) -> POFile:
    """Save the MO file for the given locale in PO format."""
    mofile_path = Path(_global_mo_path(wowsdir, locale))
    if not exists(mofile_path):
        raise OSError(f"MO file for locale {locale} not found")
    mof = mofile(mofile_path)
    mof.save_as_pofile(f"{outputdir}/{mofile_path.stem}_{locale}.po")


def get_mo(wowsdir: str, locale: str) -> MOFile:
    """Open and return the global MO file in the given directory."""
    return mofile(_global_mo_path(wowsdir, locale))


def restore_original_mo(wowsdir: str, locale: str) -> None:
    """Reinstate the original `global.mo` from `global.mo.original`."""
    global_mo_path = _global_mo_path(wowsdir, locale)
    backup_mo_path = _backup_mo_path(wowsdir, locale)
    if exists(backup_mo_path):
        _copyfile_and_checksum(backup_mo_path, global_mo_path)
        remove(backup_mo_path)


def _copyfile_and_checksum(from_path, to_path) -> None:
    """Copy a file from from_path to to_path.

    Raises OSError if the new file's checksum doesn't match the original."""
    copyfile(from_path, to_path)
    copystat(from_path, to_path)
    hasher = FileHash("md5")
    if hasher.hash_file(from_path) != hasher.hash_file(to_path):
        raise OSError("Copy failed, hash mismatch detected")


def _backup_mo_path(wowsdir: str, locale: str) -> str:
    return f"{_global_mo_path(wowsdir, locale)}.original"


def _global_mo_path(wowsdir: str, locale: str) -> str:
    return f"{wowsdir}/res/texts/{locale}/LC_MESSAGES/global.mo"
# -*- coding: utf-8 -*- Gettext manipulation methods. Apply all changes in the provided list of changes to the given MOFile. Copy the original `global.mo` to `global.mo.original`. Save the MO file for the given locale in PO format. Open and return the global MO file in the given directory. Reinstate the original `global.mo` from `global.mo.original`. Copy a file from from_path to to_path.      Raises OSError if the new file's checksum doesn't match the original.