import warnings
import numpy as np
from qiskit import IBMQ, execute, transpile, BasicAer
from qiskit_optimization.algorithms import CplexOptimizer
from qiskit_optimization import QuadraticProgram
from qiskit.visualization import plot_histogram
from qiskit.providers.ibmq.job import job_monitor

from utilities.helpers import create_qaoa_meo

# select linear program to solve
qp = QuadraticProgram()
qp.read_from_lp_file("example.lp")
# solve classically as reference
cplex = CplexOptimizer()
print(cplex.solve(qp))
print(qp)

# solve qp with Minimum Eigen Optimizer and QAOA
SHOTS = 1024
EVALUATIONS = 5
def qaoa_callback(eval_ct: int, opt_pars: np.ndarray, mean: float, stdev: float) -> None:
    """Print parameterset of last iteration."""
    if eval_ct == EVALUATIONS:
        print("Evaluation count reached ", eval_ct, "with pars:", opt_pars)

warnings.filterwarnings("ignore", category=DeprecationWarning)
qaoa = create_qaoa_meo(max_iter=EVALUATIONS, qaoa_callback=qaoa_callback, shots=SHOTS)
res = qaoa.solve(qp)
res

circuit = qaoa.min_eigen_solver.get_optimal_circuit()
circuit.measure_all()
result_meas = execute(circuit, BasicAer.get_backend('qasm_simulator'), shots=SHOTS)
counts = result_meas.result().get_counts()
plot_histogram(counts)

circuit.draw()

# to this later for belem!
for meas, count in sorted(counts.items(), key= lambda item: item[1], reverse=True):
    print(meas[::-1]," : ",count) # x0, x1, x2 sorted by count

backend = least_busy(provider.backends(filters=lambda x: x.configuration().n_qubits >= 3
                                    and not x.configuration().simulator
                                    and x.status().operational==True))
print(backend)

job = execute(circuit, backend, shots=shots, job_name="qaoa_3_real", job_tags=["qaoa", "least busy"])
job_monitor(job)

counts = job.result().get_counts()
plot_histogram(counts)