import os
import subprocess

import backoff


class GSUtilResumableUploadException(Exception):
    pass


def _decode_to_str_if_bytes(s, encoding="utf-8"):
    if isinstance(s, bytes):
        return s.decode(encoding)
    else:
        return s


def authenticate():
    try:
        credentials = os.environ["GOOGLE_APPLICATION_CREDENTIALS"]
    except KeyError:
        pass
    else:
        subprocess.check_call(
            ["gcloud", "auth", "activate-service-account", "--key-file", credentials]
        )


@backoff.on_exception(backoff.expo, GSUtilResumableUploadException, max_tries=3)
def upload_dir(d, dest):
    try:
        # Pipe stderr to stdout because gsutil logs upload progress there.
        subprocess.check_output(
            ["gsutil", "-m", "rsync", "-r", "-e", d, dest], stderr=subprocess.STDOUT
        )
    except subprocess.CalledProcessError as e:
        output = _decode_to_str_if_bytes(e.output)
        if "ResumableUploadException" in output:
            raise GSUtilResumableUploadException()
        else:
            raise e


def download_directory(dir_, dest):
    os.makedirs(dest, exist_ok=True)
    subprocess.check_call(["gsutil", "-m", "rsync", "-r", dir_, dest])


def cp(source, destination):
    subprocess.check_call(["gsutil", "cp", source, destination])

[((29, 1, 29, 80), 'backoff.on_exception', 'backoff.on_exception', (), '', False, 'import backoff\n'), ((45, 4, 45, 36), 'os.makedirs', 'os.makedirs', (), '', False, 'import os\n'), ((46, 4, 46, 70), 'subprocess.check_call', 'subprocess.check_call', ({(46, 26, 46, 69): "['gsutil', '-m', 'rsync', '-r', dir_, dest]"}, {}), "(['gsutil', '-m', 'rsync', '-r', dir_, dest])", False, 'import subprocess\n'), ((50, 4, 50, 64), 'subprocess.check_call', 'subprocess.check_call', ({(50, 26, 50, 63): "['gsutil', 'cp', source, destination]"}, {}), "(['gsutil', 'cp', source, destination])", False, 'import subprocess\n'), ((24, 8, 26, 9), 'subprocess.check_call', 'subprocess.check_call', ({(25, 12, 25, 85): "['gcloud', 'auth', 'activate-service-account', '--key-file', credentials]"}, {}), "(['gcloud', 'auth', 'activate-service-account',\n    '--key-file', credentials])", False, 'import subprocess\n'), ((33, 8, 35, 9), 'subprocess.check_output', 'subprocess.check_output', (), '', False, 'import subprocess\n')]