#!/usr/bin/env python3

import os
import getpass
from dataclasses import dataclass

import requests
from annexremote import Master
from annexremote import SpecialRemote
from annexremote import RemoteError


api_url: str = "https://data-proxy.ebrains.eu/api/v1"

class MyRemote(SpecialRemote):

    def _stat(self):
        self.authorization_headers = {
            "Authorization": f"Bearer {os.environ['EBRAINS_TOKEN']}"
        }
        self.bucket_name = os.environ['BUCKET_NAME']
        url = f"{api_url}/buckets/{self.bucket_name}/stat"
        stat = requests.get(url, headers=self.authorization_headers)
        return stat

    def initremote(self):
        print('initremote', self._stat().json())

    def prepare(self):
        print('prepare', self._stat().json())

    def transfer_store(self, key, filename):
        print('transfer_store', key, filename)
        # store the file in `filename` to a unique location derived from `key`
        # raise RemoteError if the file couldn't be stored
        try:
            url = f"{api_url}/buckets/{self.bucket_name}/{key}"
            ul_url = requests.put(url, headers=self.authorization_headers).json()['url']
            cmd = f"curl '{ul_url}' --upload-file '{filename}'"
            # print(cmd)
            os.system(cmd)
        except Exception as e:
            raise RemoteError(f'Upload failed: {e}')

    def transfer_retrieve(self, key, filename):
        print('transfer_retrieve', key, filename)
        try:
            url = f"{api_url}/buckets/{self.bucket_name}/{key}?redirect=false"
            js = requests.get(url, headers=self.authorization_headers).json()
            # print(js)
            dl_url = js['url']
            cmd = f"curl '{dl_url}' --output '{filename}'"
            # print(cmd)
            os.system(cmd)
        except Exception as e:
            raise RemoteError(f'Download failed: {e}')
        # get the file identified by `key` and store it to `filename`
        # raise RemoteError if the file couldn't be retrieved

    def checkpresent(self, key):
        print('checkpresent', key)
        try:
            url = f"{api_url}/buckets/{self.bucket_name}"
            js = requests.get(
                    url, params={'prefix': key},
                    headers=self.authorization_headers).json()
            return len(js['objects']) > 0
        except Exception as e:
            raise RemoteError(str(e))
        # return True if the key is present in the remote
        # return False if the key is not present
        # raise RemoteError if the presence of the key couldn't be determined, eg. in case of connection error
        
    def remove(self, key):
        print('remove', key)
        try:
            url = f"{api_url}/buckets/{self.bucket_name}/{key}"
            resp = requests.delete(url, headers=self.authorization_headers)
            if not resp.ok:
                raise RemoteError(resp.text)
        except Exception as e:
            raise RemoteError(str(e))
        # remove the key from the remote
        # raise RemoteError if it couldn't be removed


def test_remote():
    master = Master()
    remote = MyRemote(master)
    master.LinkRemote(remote)
    #master.Listen()
    remote.initremote()
    remote.prepare()
    remote.transfer_store('foo', 'git-annex-remote-dataproxy')
    remote.transfer_retrieve('foo', 'bar')
    print('check preset foo', remote.checkpresent('foo'))
    print('check preset bar', remote.checkpresent('bar'))
    remote.remove('foo')
    try:
        remote.remove('bar')
    except Exception as e:
        print(e)

if __name__ == '__main__':
    test_remote()
