/* osgEarth
 * Copyright 2025 Pelican Mapping
 * MIT License
 */
#pragma once

#include <osgEarth/ScriptEngine>
#include <osgEarth/Script>
#include <osgEarth/Feature>
#include <osgEarth/Containers>
#include "duktape.h"

namespace osgEarth { namespace Drivers { namespace Duktape
{
    using namespace osgEarth;

    /**
     * JavaScript engine built on the Duktape embeddable Javascript
     * interpreter. http://duktape.org
     */
    class DuktapeEngine : public osgEarth::ScriptEngine
    {
    public:
        /** Construct the engine */
        DuktapeEngine(const ScriptEngineOptions& options);

        /** Report language support */
        bool supported(std::string lang) { 
            return osgEarth::toLower(lang).compare("javascript") == 0;
        }

        /** Run a javascript code snippet. */
        ScriptResult run(
            const std::string& code,
            osgEarth::Feature* feature,
            osgEarth::FilterContext const* context) override;

        bool run(
            const std::string& code,
            const FeatureList& features,
            std::vector<ScriptResult>& results,
            FilterContext const* context) override;

    protected:
        virtual ~DuktapeEngine();

        struct Context
        {
            Context() = default;
            ~Context();
            void initialize(const ScriptEngineOptions&, bool);
            osg::ref_ptr<Feature> _feature;
            std::string _bytecodeSource;
            bool _failed = false;
            duk_context* _ctx = nullptr;
            unsigned _errorCount = 0u;
        };

        PerThread<Context> _contexts;

        const ScriptEngineOptions _options;

        bool compile(Context& c, const std::string& code, ScriptResult& result);
    };

} } } // namespace osgEarth::Drivers::Duktape
