import java.io.BufferedReader;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.util.List;
import java.util.Map;
import java.util.UUID;

import com.nifty.cloud.ncs.NiftyCloudClientException;
import com.nifty.cloud.ncs.NiftyCloudServiceException;
import com.nifty.cloud.ncs.auth.Credentials;
import com.nifty.cloud.ncs.http.ClientProperties;
import com.nifty.cloud.ncs.service.NcsBucket;
import com.nifty.cloud.ncs.service.NcsObject;
import com.nifty.cloud.ncs.service.NcsObjectContents;
import com.nifty.cloud.ncs.service.ObjectListing;
import com.nifty.cloud.ncs.service.StorageClient;
import com.nifty.cloud.ncs.service.acl.Policy;


/**
 * ニフクラ　ストレージサービス　SDK利用サンプル
 *
 */
public class NIFCLOUDStorageSample
{
    /**
     * ニフクラ　ストレージサービス　サンプル
     */
	public static void main(String[] args) throws IOException
	{
		System.out.println("====================================================");
		System.out.println("Getting Started with NIFCLOUD Storage");
		System.out.println("====================================================\n");

		try {
			ClientProperties properties = new ClientProperties();
			StorageClient client = new StorageClient(new Credentials(new File("NIFCLOUD_storage.properties")), properties);

			String bucketName = "sample-bucket-name" + UUID.randomUUID();
			String objectName = "sample-object-name";

			// バケット作成
			System.out.println("Creating bucket " + bucketName + "\n");
			client.putBucket(bucketName);

			// バケット一覧取得
			System.out.println("Listing buckets.");
			List<NcsBucket> buckets = client.getService();
			for (NcsBucket bucket : buckets) {
				System.out.println(" - " + bucket.getName());
			}
			System.out.println();

			// オブジェクトアップロード
			System.out.println("Creating a object " + bucketName + "/" + objectName);
			String etag = client.putObject(bucketName, objectName, createSampleFile(), Policy.Private);
			System.out.println("ETag = " + etag);

			// オブジェクトダウンロード
			System.out.println("Get a object " + bucketName + "/" + objectName);
			NcsObject obj = client.getObject(bucketName, objectName, null);
			System.out.println("Content-Type: "  + obj.getContentType());
			displayTextInputStream(obj.getContent());

			// オブジェクトヘッダ取得
			System.out.println("Head an object " + bucketName + "/" + objectName);
			Map<String, Object> objhead = client.headObject(bucketName, objectName);
			for (String key : objhead.keySet()) {
				System.out.println("Metadata " + key + " - " + objhead.get(key));
			}

			// オブジェクト一覧取得
			System.out.println("Listing objects " + bucketName);
			String prefix = null;
			String marker = null;
			Integer maxKeys = null;
			ObjectListing list = client.listObjects(bucketName, prefix, marker, maxKeys);

			for (NcsObjectContents contents : list.getObjectList()) {
				System.out.println(" - " + contents.getName() + " " +
						"(size = " + contents.getSize() + ")");
			}

			// オブジェクト削除
			System.out.println("Deleting a object " + bucketName + "/" + objectName);
			client.deleteObject(bucketName, objectName);

			// バケット削除
			System.out.println("Deleting a bucket " + bucketName);
			client.deleteBucket(bucketName);

		} catch (NiftyCloudServiceException e) {
			System.out.println("Caught NiftyCloudServiceException which means your request made it " +
					"NIFCLOUD Storage, but was rejected with an error response for some reason.");
			System.out.println("Error Message:                " + e.getMessage());
			System.out.println("HTTP Status Code:             " + e.getStatusCode());
			System.out.println("Error Code:                   " + e.getErrorCode());
			System.out.println("Error Type:                   " + e.getErrorType());
			System.out.println("Request ID:                   " + e.getRequestId());
		} catch (NiftyCloudClientException e) {
            System.out.println("Caught an NiftyCloudClientException, which means the client encountered "
                    + "a serious internal problem while trying to communicate with NIFCLOUD Storage, "
                    + "such as not being able to access the network.");
            System.out.println("Error Message: " + e.getMessage());
		}
	}

    /*
     * ファイルアップロード　確認用ファイル作成
     */
    private static File createSampleFile() throws IOException
    {
        File file = File.createTempFile("nifty-java-sdk-", ".txt");
        file.deleteOnExit();

        Writer writer = new OutputStreamWriter(new FileOutputStream(file));
        writer.write("abcdefghijklmnopqrstuvwxyz\n");
        writer.write("01234567890112345678901234\n");
        writer.write("!@#$%^&*()-=[]{};':',.<>/?\n");
        writer.write("01234567890112345678901234\n");
        writer.write("abcdefghijklmnopqrstuvwxyz\n");
        writer.close();

        return file;
    }

    /*
     * オブジェクトのデータを標準出力
     */
    private static void displayTextInputStream(InputStream input) throws IOException
    {
        BufferedReader reader = new BufferedReader(new InputStreamReader(input));
        while (true) {
            String line = reader.readLine();
            if (line == null) break;

            System.out.println("    " + line);
        }
        System.out.println();
    }

}
