/*****************************************************************************
 * $CAMITK_LICENCE_BEGIN$
 *
 * CamiTK - Computer Assisted Medical Intervention ToolKit
 * (c) 2001-2025 Univ. Grenoble Alpes, CNRS, Grenoble INP - UGA, TIMC, 38000 Grenoble, France
 *
 * Visit http://camitk.imag.fr for more information
 *
 * This file is part of CamiTK.
 *
 * CamiTK is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License version 3
 * only, as published by the Free Software Foundation.
 *
 * CamiTK is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License version 3 for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * version 3 along with CamiTK.  If not, see <http://www.gnu.org/licenses/>.
 *
 * $CAMITK_LICENCE_END$
 ****************************************************************************/

#ifdef PYTHON_BINDING

#ifndef __PYTHON_HOTPLUG_ACTION_EXTENSION__
#define __PYTHON_HOTPLUG_ACTION_EXTENSION__

#include "HotPlugActionExtension.h"
#include "InterfaceLogger.h"

#include <QDir>

namespace camitk {

class PythonHotPlugAction;

/**
 * @brief A python ActionExtension that can be created on the fly from a camitk extension file.
 *
 * This class manages PythonHotPlugAction of the same python virtual env.
 *
 * The directory of the CamiTK extension file should have one python script filename per action.
 * Each python extension is managed in a specific python virtual environment
 * (located in the ".venv" subdirectory).
 *
 * If there are no python virtual environment inside the extension directory (i.e. no subdirectory
 * ".venv"), PythonHotPlugActionExtension will create one.
 * When instantiated, it will also check for python package to install in the virtual environment
 * using the "requirements" array of the camitk extension model.
 */
class CAMITK_API PythonHotPlugActionExtension : public HotPlugActionExtension {
    Q_OBJECT

public:
    /// constructor
    PythonHotPlugActionExtension(const QString& camitkFilePath, bool verifyVirtualEnv = false);

    /// destructor
    ~PythonHotPlugActionExtension() override;

    /** \enum PythonCallStatus describes the possible status of a call to a python script
      */
    enum class PythonCallStatus {
        ALREADY_IN_CALL,   // the method is already running, nothing was done
        MODULE_NOT_LOADED, // python module was not loaded properly (i.e. lockContext failed)
        MISSING_FUNCTION,  // python function is missing in the script
        NOT_A_FUNCTION,    // python function is a symbol but is not callable
        RETURNED_FALSE,    // python function returned false
        EXCEPTION_RAISED,  // python code raised an exception
        SUCCESS            // everything went well
    };

    /// get the programming language of this extension
    virtual QString getProgrammingLanguage() const override {
        return "Python";
    }

    /// instantiate all the python actions (might generate some warnings)
    /// @note this method must set the successfullyLoaded to false and return false when some action could not
    /// be instantiated
    /// @param progressMinimum is the current initial progress value
    /// @param progressMaximum is the maximum progress bar value to use when all actions are initialized
    virtual bool initActions(int progressMinimum = 0, int progressMaximum = 100) override;

    /// call python function of the given name (with a string parameter if given) in the given action script.
    /// If the python interpreter generates an exception, this method will catch it, display
    /// a warning and returns the corresponding status.
    ///
    /// The following problems can arise when calling the python script (see also enum PythonCallStatus):
    /// - methodName() is missing in the script
    /// - methodName is a python symbol, but not callable (e.g. it is not a method but for instance a variable)
    ///
    /// @return the status information
    PythonHotPlugActionExtension::PythonCallStatus callPython(PythonHotPlugAction* action, QString methodName, QString param = QString());

private:
    /// managed path
    QDir extensionDir;

    /// is venv verification required
    bool verifyVirtualEnvRequested;
};

} // namespace camitk

#endif // __PYTHON_HOTPLUG_ACTION_EXTENSION__
#endif // PYTHON_BINDING