# This code is part of Qiskit.
#
# (C) Copyright IBM 2017.
#
# This code is licensed under the Apache License, Version 2.0. You may
# obtain a copy of this license in the LICENSE.txt file in the root directory
# of this source tree or at http://www.apache.org/licenses/LICENSE-2.0.
#
# Any modifications or derivative works of this code must retain this
# copyright notice, and modified files need to carry a notice indicating
# that they have been altered from the originals.

"""Quantum Operation Mixin."""

from abc import ABC, abstractmethod


class Operation(ABC):
    """Quantum operation interface.

    The minimal interface that any object must fulfil in order to be added to a
    :class:`.QuantumCircuit`.

    Concrete instances of this interface include :class:`~qiskit.circuit.Gate`,
    :class:`~qiskit.circuit.Reset`, :class:`~qiskit.circuit.Barrier`,
    :class:`~qiskit.circuit.Measure`, and operators such as :class:`~qiskit.quantum_info.Clifford`.

    The main purpose is to add allow abstract mathematical objects to be added directly onto
    abstract circuits, and for the exact syntheses of these to be determined later, during
    compilation.

    Example:

        Add a Clifford and a Toffoli gate to a :class:`QuantumCircuit`.

        .. plot::
           :include-source:

           from qiskit import QuantumCircuit
           from qiskit.quantum_info import Clifford, random_clifford

           qc = QuantumCircuit(3)
           cliff = random_clifford(2)
           qc.append(cliff, [0, 1])
           qc.ccx(0, 1, 2)
           qc.draw('mpl')
    """

    __slots__ = ()

    @property
    @abstractmethod
    def name(self):
        """Unique string identifier for operation type."""
        raise NotImplementedError

    @property
    @abstractmethod
    def num_qubits(self):
        """Number of qubits."""
        raise NotImplementedError

    @property
    @abstractmethod
    def num_clbits(self):
        """Number of classical bits."""
        raise NotImplementedError
