/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You 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
 *
 *     http://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.
 */
package org.jclouds.b2.features;

import static org.assertj.core.api.Assertions.assertThat;
import static org.jclouds.b2.features.B2TestUtils.api;
import static org.jclouds.b2.features.B2TestUtils.assertAuthentication;
import static org.jclouds.b2.features.B2TestUtils.assertRequest;
import static org.jclouds.b2.features.B2TestUtils.createMockWebServer;
import static org.jclouds.b2.features.B2TestUtils.stringFromResource;

import okhttp3.mockwebserver.MockResponse;
import okhttp3.mockwebserver.MockWebServer;

import org.jclouds.b2.domain.Bucket;
import org.jclouds.b2.domain.BucketList;
import org.jclouds.b2.domain.BucketType;
import org.testng.annotations.Test;


@Test(groups = "unit", testName = "BucketApiMockTest")
public final class BucketApiMockTest {
   public void testCreateBucket() throws Exception {
      MockWebServer server = createMockWebServer();
      server.enqueue(new MockResponse().setBody(stringFromResource("/authorize_account_response.json")));
      server.enqueue(new MockResponse().setBody(stringFromResource("/bucket.json")));

      try {
         BucketApi api = api(server.url("/").toString(), "b2").getBucketApi();
         Bucket response = api.createBucket("any_name_you_pick", BucketType.ALL_PRIVATE);
         assertThat(response.bucketId()).isEqualTo("4a48fe8875c6214145260818");
         assertThat(response.bucketName()).isEqualTo("any_name_you_pick");
         assertThat(response.bucketType()).isEqualTo(BucketType.ALL_PRIVATE);

         assertThat(server.getRequestCount()).isEqualTo(2);
         assertAuthentication(server);
         assertRequest(server.takeRequest(), "POST", "/b2api/v2/b2_create_bucket", "/create_bucket_request.json");
      } finally {
         server.shutdown();
      }
   }

   public void testDeleteBucket() throws Exception {
      MockWebServer server = createMockWebServer();
      server.enqueue(new MockResponse().setBody(stringFromResource("/authorize_account_response.json")));
      server.enqueue(new MockResponse().setBody(stringFromResource("/bucket.json")));

      try {
         BucketApi api = api(server.url("/").toString(), "b2").getBucketApi();
         Bucket response = api.deleteBucket("4a48fe8875c6214145260818");
         assertThat(response.bucketId()).isEqualTo("4a48fe8875c6214145260818");
         assertThat(response.bucketName()).isEqualTo("any_name_you_pick");
         assertThat(response.bucketType()).isEqualTo(BucketType.ALL_PRIVATE);

         assertThat(server.getRequestCount()).isEqualTo(2);
         assertAuthentication(server);
         assertRequest(server.takeRequest(), "POST", "/b2api/v2/b2_delete_bucket", "/delete_bucket_request.json");
      } finally {
         server.shutdown();
      }
   }

   public void testDeleteAlreadyDeletedBucket() throws Exception {
      MockWebServer server = createMockWebServer();
      server.enqueue(new MockResponse().setBody(stringFromResource("/authorize_account_response.json")));
      server.enqueue(new MockResponse().setResponseCode(400).setBody(stringFromResource("/delete_bucket_already_deleted_response.json")));

      try {
         BucketApi api = api(server.url("/").toString(), "b2").getBucketApi();
         Bucket response = api.deleteBucket("4a48fe8875c6214145260818");
         assertThat(response).isNull();

         assertThat(server.getRequestCount()).isEqualTo(2);
         assertAuthentication(server);
         assertRequest(server.takeRequest(), "POST", "/b2api/v2/b2_delete_bucket", "/delete_bucket_request.json");
      } finally {
         server.shutdown();
      }
   }

   public void testUpdateBucket() throws Exception {
      MockWebServer server = createMockWebServer();
      server.enqueue(new MockResponse().setBody(stringFromResource("/authorize_account_response.json")));
      server.enqueue(new MockResponse().setBody(stringFromResource("/bucket.json")));

      try {
         BucketApi api = api(server.url("/").toString(), "b2").getBucketApi();
         Bucket response = api.updateBucket("4a48fe8875c6214145260818", BucketType.ALL_PRIVATE);
         assertThat(response.bucketId()).isEqualTo("4a48fe8875c6214145260818");
         assertThat(response.bucketName()).isEqualTo("any_name_you_pick");
         assertThat(response.bucketType()).isEqualTo(BucketType.ALL_PRIVATE);

         assertThat(server.getRequestCount()).isEqualTo(2);
         assertAuthentication(server);
         assertRequest(server.takeRequest(), "POST", "/b2api/v2/b2_update_bucket", "/update_bucket_request.json");
      } finally {
         server.shutdown();
      }
   }

   public void testListBuckets() throws Exception {
      MockWebServer server = createMockWebServer();
      server.enqueue(new MockResponse().setBody(stringFromResource("/authorize_account_response.json")));
      server.enqueue(new MockResponse().setBody(stringFromResource("/list_buckets_response.json")));

      try {
         BucketApi api = api(server.url("/").toString(), "b2").getBucketApi();
         BucketList response = api.listBuckets();

         assertThat(response.buckets()).hasSize(3);

         assertThat(response.buckets().get(0).bucketName()).isEqualTo("Kitten Videos");
         assertThat(response.buckets().get(0).bucketType()).isEqualTo(BucketType.ALL_PRIVATE);

         assertThat(response.buckets().get(1).bucketName()).isEqualTo("Puppy Videos");
         assertThat(response.buckets().get(1).bucketType()).isEqualTo(BucketType.ALL_PUBLIC);

         assertThat(response.buckets().get(2).bucketName()).isEqualTo("Vacation Pictures");
         assertThat(response.buckets().get(2).bucketType()).isEqualTo(BucketType.ALL_PRIVATE);

         assertThat(server.getRequestCount()).isEqualTo(2);
         assertAuthentication(server);
         assertRequest(server.takeRequest(), "POST", "/b2api/v2/b2_list_buckets", "/list_buckets_request.json");
      } finally {
         server.shutdown();
      }
   }
}
