// Copyright (C) 2018-2026 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
//

#pragma once

#include <cstddef>
#include <memory>

#include "openvino/core/node.hpp"
#include "openvino/core/node_vector.hpp"
#include "openvino/op/op.hpp"
#include "snippets/lowered/linear_ir.hpp"

namespace ov::snippets::op {

/**
 * @interface Kernel
 * @brief Generated by Canonicalization and represents compute kernel legal for scheduling
 * @ingroup snippets
 */
class Kernel : public ov::op::Op {
public:
    OPENVINO_OP("Kernel", "SnippetsOpset");
    Kernel() = default;
    explicit Kernel(lowered::LinearIR region);

    template <typename... ArgTypes>
    static std::shared_ptr<Kernel> make_kernel(bool is_dynamic, ArgTypes&&... args);
    virtual size_t get_num_call_args() const = 0;

    std::shared_ptr<lowered::LinearIR> region = nullptr;
    const void* compile_params = nullptr;
};

class KernelStatic : public Kernel {
public:
    OPENVINO_OP("KernelStatic", "SnippetsOpset", Kernel);
    KernelStatic() = default;
    explicit KernelStatic(lowered::LinearIR region);
    size_t get_num_call_args() const override {
        return 2;
    }
    std::shared_ptr<Node> clone_with_new_inputs(const OutputVector& inputs) const override;
};

class KernelDynamic : public Kernel {
public:
    OPENVINO_OP("KernelDynamic", "SnippetsOpset", Kernel);
    KernelDynamic() = default;
    explicit KernelDynamic(lowered::LinearIR region);
    size_t get_num_call_args() const override {
        return 1;
    }
    std::shared_ptr<Node> clone_with_new_inputs(const OutputVector& inputs) const override;
};

template <typename... ArgTypes>
std::shared_ptr<Kernel> Kernel::make_kernel(bool is_dynamic, ArgTypes&&... args) {
    if (is_dynamic) {
        return std::make_shared<KernelDynamic>(std::forward<ArgTypes>(args)...);
    }
    return std::make_shared<KernelStatic>(std::forward<ArgTypes>(args)...);
}

}  // namespace ov::snippets::op
