#!/usr/bin/env python

import os

import pytest

boto3 = pytest.importorskip('boto3')
from simplekv.net.botostore import BotoStore
from simplekv._compat import BytesIO

from basic_store import BasicStore
from url_store import UrlStore
from bucket_manager import boto_credentials, boto3_bucket
from conftest import ExtendedKeyspaceTests
from simplekv.contrib import ExtendedKeyspaceMixin


@pytest.fixture(params=boto_credentials,
                ids=[c['access_key'] for c in boto_credentials])
def credentials(request):
    return request.param


@pytest.yield_fixture()
def bucket(credentials):
    with boto3_bucket(**credentials) as bucket:
        yield bucket


class TestBotoStorage(BasicStore, UrlStore):
    @pytest.fixture(params=[True, False])
    def reduced_redundancy(self, request):
        return request.param

    @pytest.fixture
    def storage_class(self, reduced_redundancy):
        return 'REDUCED_REDUNDANCY' if reduced_redundancy else 'STANDARD'

    @pytest.fixture(params=['', '/test-prefix'])
    def prefix(self, request):
        return request.param

    @pytest.fixture
    def store(self, bucket, prefix, reduced_redundancy):
        return BotoStore(bucket, prefix, reduced_redundancy=reduced_redundancy)

    # Disable max key length test as it leads to problems with minio
    test_max_key_length = None

    def test_get_filename_nonexistant(self, store, key, tmp_path):
        with pytest.raises(KeyError):
            store.get_file(key, os.path.join(str(tmp_path), 'a'))

    def test_key_error_on_nonexistant_get_filename(self, store, key, tmp_path):
        with pytest.raises(KeyError):
            store.get_file(key, os.path.join(str(tmp_path), 'a'))

    def test_storage_class_put(
        self, store, prefix, key, value, storage_class, bucket
    ):
        store.put(key, value)

        keyname = prefix + key

        if storage_class != 'STANDARD':
            pytest.xfail('boto does not support checking the storage class?')

        assert bucket.Object(keyname).storage_class == storage_class

    def test_storage_class_putfile(
        self, store, prefix, key, value, storage_class, bucket
    ):
        store.put_file(key, BytesIO(value))

        keyname = prefix + key

        if storage_class != 'STANDARD':
            pytest.xfail('boto does not support checking the storage class?')
        assert bucket.Object(keyname).storage_class == storage_class


class TestExtendedKeyspaceBotoStore(TestBotoStorage, ExtendedKeyspaceTests):
    @pytest.fixture
    def store(self, bucket, prefix, reduced_redundancy):
        class ExtendedKeyspaceStore(ExtendedKeyspaceMixin, BotoStore):
            pass
        return ExtendedKeyspaceStore(bucket, prefix,
                                     reduced_redundancy=reduced_redundancy)

@@ -101,16 +101,17 @@
 net.boto
+3
 store im
@@ -115,24 +115,25 @@
  import Boto
+3
 Store%0Afrom s
@@ -673,24 +673,25 @@
 ass TestBoto
+3
 Storage(Basi
@@ -1132,36 +1132,16 @@
 , prefix
-, reduced_redundancy
 ):%0A     
@@ -1150,24 +1150,25 @@
  return Boto
+3
 Store(bucket
@@ -1179,47 +1179,8 @@
 efix
-, reduced_redundancy=reduced_redundancy
 )%0A%0A 
@@ -2388,24 +2388,25 @@
 KeyspaceBoto
+3
 Store(TestBo
@@ -2403,24 +2403,25 @@
 ore(TestBoto
+3
 Storage, Ext
@@ -2495,36 +2495,16 @@
 , prefix
-, reduced_redundancy
 ):%0A     
@@ -2561,16 +2561,17 @@
 in, Boto
+3
 Store):%0A
@@ -2642,82 +2642,6 @@
 efix
-,%0A                                     reduced_redundancy=reduced_redundancy
 )%0A

Fix bugs in the Boto3 unit tests