# Copyright (C) 2023 - 2025 ANSYS, Inc. and/or its affiliates.
# SPDX-License-Identifier: MIT
#
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in all
# copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.

r""".. _ref_run_chemkin_java_gui:

===================================
Run Chemkin Workbench GUI in Python
===================================
GUI workflow for running Chemkin Workbench from Python.

This GUI wraps the high-level workflow used to launch Chemkin Workbench from
the command line, which consists of the following steps:
1) generate a platform-specific run script,
2) execute the script with subprocess.
"""

################################################
# Import PyChemkin packages and start the logger
# ==============================================
from pathlib import Path
import platform
import subprocess

from ansys.chemkin.core import Color
from ansys.chemkin.core.chemistry import chemkin_bin_dir
from ansys.chemkin.core.logger import logger

###########################################
# Establish the chemkin runtime environment
# =========================================
# The batch script to establish the chemkin runtime environment is platform
# dependent. The first task is to find out the platform and the shell environment.
# Then you will run the environment setup script accordingly.

# Get local Ansys Chemkin installation bin folder
ckbin = Path(chemkin_bin_dir())

# Configure platform-dependent executable/env names.
under_win = platform.system() == "Windows"
if under_win:
    # Windows platform
    env_file = "run_chemkin_env_setup.bat"
    run_env_path = ckbin / env_file
    java_file = "run_rdworkbench.bat"
    run_java_path = ckbin / java_file

elif platform.system() == "Linux":
    # Linux platform
    env_file = "chemkin_setup.ksh"
    run_env_path = ckbin / env_file
    java_file = "run_rdworkbench.ksh"
    run_java_path = ckbin / java_file
else:
    raise RuntimeError(f"Unsupported platform: {platform.system()}")
# check files exist
if not run_env_path.is_file():
    raise FileNotFoundError(f"Chemkin setup script not found: {run_env_path}")
if not run_java_path.is_file():
    raise FileNotFoundError(f"Chemkin GUI launcher not found: {run_java_path}")

# Create run script.
if under_win:
    # Windows platform
    script_path = Path.cwd() / "RUN_CKjob_gui.bat"
    with script_path.open("w", encoding="utf-8") as script:
        script.write("@REM Generated by run_chemkin_workbench_gui.py\n")
        script.write(f'@CALL "{run_env_path}"\n')
        script.write("@SET MKL_NUM_THREADS=1\n")
        script.write("@SET OMP_NUM_THREADS=1\n")
        script.write("@SET XERCES_DISABLE_DTD=1\n")
        script.write(f'@CALL "{run_java_path}"\n')
        script.write(r"@IF %ERRORLEVEL% NEQ 0 EXIT /B %ERRORLEVEL%")
        script.write("\n")
else:
    # Linux platform
    script_path = Path.cwd() / "RUN_CKjob_gui.sh"
    with script_path.open("w", encoding="utf-8") as script:
        script.write("#!/bin/bash\n")
        script.write("set -e\n")
        script.write(f'. "{run_env_path}"\n')
        script.write("export MKL_NUM_THREADS=1\n")
        script.write("export OMP_NUM_THREADS=1\n")
        script.write("export XERCES_DISABLE_DTD=1\n")
        script.write(f'. "{run_java_path}"\n')

logger.info(f"Created run script: {script_path}")

# Execute run script with subprocess.
try:
    if under_win:
        run_cmd = ["cmd", "/d", "/c", str(script_path)]
    else:
        run_cmd = ["bash", str(script_path)]

    result = subprocess.run(
        run_cmd,
        capture_output=True,
        text=True,
        check=True,
        shell=False,
    )
    # Log stderr if they exist.
    if result.stderr:
        msg = [
            Color.PURPLE,
            "--- stderr ---\n",
            Color.SPACEx6,
            result.stderr.rstrip(),
            Color.END,
        ]
        this_msg = Color.SPACE.join(msg)
        logger.error(this_msg)
except subprocess.CalledProcessError as e:
    if not e.returncode == 1:  # return code 1 is expected when user closes the GUI
        logger.error(f"Chemkin Java GUI failed with return code {e.returncode}")
        result = e  # capture the error output for logging
        if result.stderr:
            msg = [
                Color.PURPLE,
                "process error\n",
                Color.SPACEx6,
                result.stderr.rstrip(),
                Color.END,
            ]
            this_msg = Color.SPACE.join(msg)
            logger.error(this_msg)

# clean up run script
try:
    script_path.unlink()
    logger.info(f"Deleted run script: {script_path}")
except Exception as e:
    logger.warning(f"Failed to delete run script: {script_path}. Error: {e}")
