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 javax.crypto.SecretKey;

import com.nifty.cloud.ncs.NiftyCloudClientException;
import com.nifty.cloud.ncs.NiftyCloudServiceException;
import com.nifty.cloud.ncs.auth.Credentials;
import com.nifty.cloud.ncs.encrypt.CryptoConfiguration;
import com.nifty.cloud.ncs.encrypt.CryptoStorageMode;
import com.nifty.cloud.ncs.encrypt.EncryptionKeyMaterials;
import com.nifty.cloud.ncs.encrypt.PrivateKeyGenerator;
import com.nifty.cloud.ncs.http.ClientProperties;
import com.nifty.cloud.ncs.service.NcsObject;
import com.nifty.cloud.ncs.service.StorageEncryptionClient;
import com.nifty.cloud.ncs.service.acl.Policy;


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

		try {
			File propertiesFile = new File("NIFCLOUD_storage.properties");
			Credentials credentials = new Credentials(propertiesFile);
			ClientProperties properties = new ClientProperties();

			PrivateKeyGenerator keyGenerator = new PrivateKeyGenerator(propertiesFile);
			SecretKey privateKey = keyGenerator.generatePrivateKey();
			EncryptionKeyMaterials materials = new EncryptionKeyMaterials(privateKey);
			CryptoConfiguration cryptoConfig = new CryptoConfiguration();
			cryptoConfig.setStorageMode(CryptoStorageMode.InstructionFile);
			StorageEncryptionClient encryptionClient = new StorageEncryptionClient(credentials, properties, materials, cryptoConfig);

			String bucketName = "sample-bucket-name";
			String encryptedObjectName = "sample-object-name-encrypt";

			// 暗号化オブジェクトアップロード
			System.out.println("Creating a object " + bucketName + "/" + encryptedObjectName + " using encryption");
			String etag = encryptionClient.putObject(bucketName, encryptedObjectName, createSampleFile(), Policy.Private);
			System.out.println("ETag = " + etag);

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

			// 暗号化オブジェクト削除
			System.out.println("Deleting a object " + bucketName + "/" + encryptedObjectName);
			encryptionClient.deleteObject(bucketName, encryptedObjectName);

		} 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();
    }
}
