# Copyright 2020 Google
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

import asyncio
import datetime
import math
import os
import uuid
from dataclasses import dataclass, field
from typing import List, Any, Optional, Callable, Dict, Union

import numpy as np

import cirq
import cirq_google as cg
from cirq import work, study, circuits, ops
from cirq_google.engine.engine_job import TERMINAL_STATES


def _get_program_id(program: Any):
    """Get a program id from program.program_id.

    This is not an actual attribute of cirq.Circuit, but thanks to the magic
    of python, it can be! If your circuit does not have a program_id,
    this function will return a uuid4().

    Program ids can only contain alphanumeric and -_ so we replace
    "/" and ":" which are common in our data collection idioms.
    Program ids must be unique and sometimes you need to re-try a particular
    experiment, so we append a random component.

    Program ids can only be 64 characters. The following
    compression is performed: the program id is split according to `/`
    and the middle part of each resulting string is omitted to get the