# Path: qflexcirq/interface/qflex_order.py
# class QFlexOrder():
# 
#     def __init__(self,
#                  qflex_order_strings=None,
#                  cirq_circuit=None,
#                  qubits=None):
# 
#         if (qflex_order_strings is None) and (cirq_circuit is None):
#             # TODO: More serious checking
#             raise ValueError("No order specified to constructor!")
# 
#         if (cirq_circuit is not None) and (not isinstance(
#                 cirq_circuit, cirq.Circuit)):
#             raise ValueError("Order accepts only QFlexCircuits")
# 
#         ord_list = qflex_order_strings
#         if cirq_circuit is not None:
# 
#             if qubits is None:
#                 raise ValueError("Qubits have to be specified!")
# 
#             # The device has to be QFlex
#             # qubits = qflex_circuit.device.get_indexed_grid_qubits()
#             # List of ordering commands
#             print("Ordering is being computed from the provided circuit ...")
#             ord_list = auto_order.circuit_to_ordering(
#                 cirq_circuit, qubit_names=sorted(qubits))
#             print("... Done!")
# 
#         # Long string of ordering commands
#         _local_order_string = '\n'.join([x.strip() for x in ord_list])
# 
#         # Behind the scene, this class creates a temporary file for each object
#         self.temp_file_if = tmpi.DataStorageInterface()
# 
#         with open(self.temp_file_if.fullpath, "w") as f:
#             # I do have the file handle anyway...
#             print(_local_order_string, file=f)
# 
#     @property
#     def order_data(self):
#         return self.temp_file_if.fullpath
# 
#     @staticmethod
#     def from_existing_file(file_path):
#         with open(file_path, "r") as f:
#             lines = f.readlines()
#             return QFlexOrder(qflex_order_strings=lines)
# 
# Path: qflexcirq/ordering/order_circuit_simulation.py
# def powerset(iterable):
#     def __init__(self, nodes):
#     def dim(self):
#     def add_op(self, op):
#     def swap_nodes(self, old_nodes, new_nodes):
#     def get_remote_bonds(self):
#     def get_remote_nodes(self):
#     def get_cost(self):
#     def __hash__(self):
#     def __eq__(self, other):
#     def __repr__(self):
#     def __str__(self):
#     def __init__(self, qubits):
#     def rank(self):
#     def add_bond(self, bond):
#     def remove_bond(self, bond):
#     def __hash__(self):
#     def __eq__(self, other):
#     def __init__(self, qubits):
#     def create_node(self, qubits):
#     def add_bond(self, qubits, op):
#     def update_bonds(self, bonds):
#     def contract(self, bond):
# def create_ordering_data(
#     contraction_steps: Iterable[cirq.ops.raw_types.Operation],
#     qubit_names: Iterable[int], qubit_order: Tuple[cirq.ops.raw_types.Qid,
#                                                    ...]):
# def get_steps_for_graph(g: Graph):
# def match_fidelity(target_fidelity: float, cuts: Dict[frozenset, int]):
# def circuit_to_ordering(
#     circuit: cirq.circuits.Circuit,
#     qubit_names: Iterable[int] = None,
#     qubit_order_method: cirq.ops.QubitOrderOrList = cirq.ops.QubitOrder.DEFAULT,
#     max_cuts: int = 2,
#     fidelity: float = 1.0):
# class Bond:
# class Node:
# class Graph:


import random
import cirq
import pytest
import sys
    import tempfile
    import os
from qflexcirq import QFlexOrder
from qflexcirq.ordering import order_circuit_simulation as order_lib

def test_only_for_cirq_circuits():
    """
    If no strings are specified, the only other option is a Cirq circuit
    :return:
    """
    with pytest.raises(ValueError):
        assert QFlexOrder(qflex_order_strings=None, cirq_circuit="Should fail")


def test_cirquit_without_qubits():
    """
    If the Cirq circuit is specified a list of qubits is also necessary
    :return:
    """
    with pytest.raises(ValueError):
        assert QFlexOrder(qflex_order_strings=None,
                          cirq_circuit=cirq.Circuit([]))


def test_automatic_ordering():

    test_size = 2
    test_circuit = generate_circuit(size=test_size)

    # This is a known order
    random.seed(0)
    order = order_lib.circuit_to_ordering(test_circuit)

    # Now I am creating a QFlexOrder

# Path: qflexcirq/interface/qflex_order.py
# class QFlexOrder():
# 
#     def __init__(self,
#                  qflex_order_strings=None,
#                  cirq_circuit=None,
#                  qubits=None):
# 
#         if (qflex_order_strings is None) and (cirq_circuit is None):
#             # TODO: More serious checking
#             raise ValueError("No order specified to constructor!")
# 
#         if (cirq_circuit is not None) and (not isinstance(
#                 cirq_circuit, cirq.Circuit)):
#             raise ValueError("Order accepts only QFlexCircuits")
# 
#         ord_list = qflex_order_strings
#         if cirq_circuit is not None:
# 
#             if qubits is None:
#                 raise ValueError("Qubits have to be specified!")
# 
#             # The device has to be QFlex
#             # qubits = qflex_circuit.device.get_indexed_grid_qubits()
#             # List of ordering commands
#             print("Ordering is being computed from the provided circuit ...")
#             ord_list = auto_order.circuit_to_ordering(
#                 cirq_circuit, qubit_names=sorted(qubits))
#             print("... Done!")
# 
#         # Long string of ordering commands
#         _local_order_string = '\n'.join([x.strip() for x in ord_list])
# 
#         # Behind the scene, this class creates a temporary file for each object
#         self.temp_file_if = tmpi.DataStorageInterface()
# 
#         with open(self.temp_file_if.fullpath, "w") as f:
#             # I do have the file handle anyway...
#             print(_local_order_string, file=f)
# 
#     @property
#     def order_data(self):
#         return self.temp_file_if.fullpath
# 
#     @staticmethod
#     def from_existing_file(file_path):
#         with open(file_path, "r") as f:
#             lines = f.readlines()
#             return QFlexOrder(qflex_order_strings=lines)
# 
# Path: qflexcirq/ordering/order_circuit_simulation.py
# def powerset(iterable):
#     def __init__(self, nodes):
#     def dim(self):
#     def add_op(self, op):
#     def swap_nodes(self, old_nodes, new_nodes):
#     def get_remote_bonds(self):
#     def get_remote_nodes(self):
#     def get_cost(self):
#     def __hash__(self):
#     def __eq__(self, other):
#     def __repr__(self):
#     def __str__(self):
#     def __init__(self, qubits):
#     def rank(self):
#     def add_bond(self, bond):
#     def remove_bond(self, bond):
#     def __hash__(self):
#     def __eq__(self, other):
#     def __init__(self, qubits):
#     def create_node(self, qubits):
#     def add_bond(self, qubits, op):
#     def update_bonds(self, bonds):
#     def contract(self, bond):
# def create_ordering_data(
#     contraction_steps: Iterable[cirq.ops.raw_types.Operation],
#     qubit_names: Iterable[int], qubit_order: Tuple[cirq.ops.raw_types.Qid,
#                                                    ...]):
# def get_steps_for_graph(g: Graph):
# def match_fidelity(target_fidelity: float, cuts: Dict[frozenset, int]):
# def circuit_to_ordering(
#     circuit: cirq.circuits.Circuit,
#     qubit_names: Iterable[int] = None,
#     qubit_order_method: cirq.ops.QubitOrderOrList = cirq.ops.QubitOrder.DEFAULT,
#     max_cuts: int = 2,
#     fidelity: float = 1.0):
# class Bond:
# class Node:
# class Graph:


# Path: tests/python/qflex_order_test.py
import random
import cirq
import pytest
import sys
    import tempfile
    import os
from qflexcirq import QFlexOrder
from qflexcirq.ordering import order_circuit_simulation as order_lib


def test_only_for_cirq_circuits():
    """
    If no strings are specified, the only other option is a Cirq circuit
    :return:
    """
    with pytest.raises(ValueError):
        assert QFlexOrder(qflex_order_strings=None, cirq_circuit="Should fail")


def test_cirquit_without_qubits():
    """
    If the Cirq circuit is specified a list of qubits is also necessary
    :return:
    """
    with pytest.raises(ValueError):
        assert QFlexOrder(qflex_order_strings=None,
                          cirq_circuit=cirq.Circuit([]))


def test_automatic_ordering():

    test_size = 2
    test_circuit = generate_circuit(size=test_size)

    # This is a known order
    random.seed(0)
    order = order_lib.circuit_to_ordering(test_circuit)

    # Now I am creating a QFlexOrder

    qorder = QFlexOrder(qflex_order_strings=None,