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])

[((518, 597), 'backoff.on_exception', 'backoff.on_exception', (['backoff.expo', 'GSUtilResumableUploadException'], {'max_tries': '(3)'}), '(backoff.expo, GSUtilResumableUploadException, max_tries=3)\n', (538, 597), False, 'import backoff\n'), ((1109, 1141), 'os.makedirs', 'os.makedirs', (['dest'], {'exist_ok': '(True)'}), '(dest, exist_ok=True)\n', (1120, 1141), False, 'import os\n'), ((1146, 1212), 'subprocess.check_call', 'subprocess.check_call', (["['gsutil', '-m', 'rsync', '-r', dir_, dest]"], {}), "(['gsutil', '-m', 'rsync', '-r', dir_, dest])\n", (1167, 1212), False, 'import subprocess\n'), ((1248, 1308), 'subprocess.check_call', 'subprocess.check_call', (["['gsutil', 'cp', source, destination]"], {}), "(['gsutil', 'cp', source, destination])\n", (1269, 1308), False, 'import subprocess\n'), ((396, 496), 'subprocess.check_call', 'subprocess.check_call', (["['gcloud', 'auth', 'activate-service-account', '--key-file', credentials]"], {}), "(['gcloud', 'auth', 'activate-service-account',\n    '--key-file', credentials])\n", (417, 496), False, 'import subprocess\n'), ((715, 816), 'subprocess.check_output', 'subprocess.check_output', (["['gsutil', '-m', 'rsync', '-r', '-e', d, dest]"], {'stderr': 'subprocess.STDOUT'}), "(['gsutil', '-m', 'rsync', '-r', '-e', d, dest],\n    stderr=subprocess.STDOUT)\n", (738, 816), False, 'import subprocess\n')]