package com.qiniu.api.rs;

import org.json.JSONException;
import org.json.JSONStringer;

import com.qiniu.api.auth.AuthException;
import com.qiniu.api.auth.digest.DigestAuth;
import com.qiniu.api.auth.digest.Mac;

/**
 * The PutPolicy class used to generate a upload token. To upload a file, you
 * should obtain upload authorization from Qiniu cloud strage platform. By a
 * pair of valid accesskey and secretkey, we generate a upload token. When
 * upload a file, the upload token is transmissed as a part of the file stream,
 * or as an accessory part of the HTTP Headers.
 */

public class PutPolicy {
	/** 必选。可以是 bucketName 或者 bucketName:key */
	public String scope;
	/** 可选 */
	public String callbackUrl;
	/** 可选 */
	public String callbackBody;
	/** 可选 */
	public String returnUrl;
	/** 可选 */
	public String returnBody;
	/** 可选 */
	public String asyncOps;
	/** 可选 */
	public String endUser;
	/** 可选 */
	public long expires;

	public PutPolicy(String scope) {
		this.scope = scope;
	}

	private String marshal() throws JSONException {
		JSONStringer stringer = new JSONStringer();
		stringer.object();
		stringer.key("scope").value(this.scope);
		if (this.callbackUrl != null && this.callbackUrl.length() > 0) {
			stringer.key("callbackUrl").value(this.callbackUrl);
		}
		if (this.returnUrl != null && this.returnUrl.length() > 0) {
			stringer.key("returnUrl").value(this.returnUrl);
		}
		if (this.asyncOps != null && this.asyncOps.length() > 0) {
			stringer.key("asyncOps").value(this.asyncOps);
		}

		if (this.returnBody != null && this.returnBody.length() > 0) {
			stringer.key("returnBody").value(this.returnBody);
		}

		stringer.key("deadline").value(this.expires);
		stringer.endObject();

		return stringer.toString();
	}

	
	/**
	 * makes an upload token.
	 * @param mac
	 * @return
	 * @throws AuthException
	 * @throws JSONException
	 */
	
	public String token(Mac mac) throws AuthException, JSONException {
		if (this.expires == 0) {
			this.expires = 3600; // 3600s, default.
		}
		this.expires = System.currentTimeMillis() / 1000 + expires;
		byte[] data = this.marshal().getBytes();
		return DigestAuth.signWithData(mac, data);
	}

}

@@ -1281,25 +1281,28 @@
 f (this.
-returnUrl
+callbackBody
  != null
@@ -1310,25 +1310,28 @@
 && this.
-returnUrl
+callbackBody
 .length(
@@ -1356,25 +1356,28 @@
 er.key(%22
-returnUrl
+callbackBody
 %22).value
@@ -1382,25 +1382,28 @@
 ue(this.
-returnUrl
+callbackBody
 );%0A%09%09%7D%0A%09
@@ -1412,24 +1412,25 @@
 f (this.
-asyncOps
+returnUrl
  != null
@@ -1438,24 +1438,25 @@
 && this.
-asyncOps
+returnUrl
 .length(
@@ -1481,24 +1481,25 @@
 er.key(%22
-asyncOps
+returnUrl
 %22).value
@@ -1508,24 +1508,24 @@
 his.
-asyncOps
+returnUrl
 );%0A%09%09%7D%0A
-%0A
 %09%09if
@@ -1643,16 +1643,130 @@
 y);%0A%09%09%7D%0A
+%09%09if (this.asyncOps != null && this.asyncOps.length() %3E 0) %7B%0A%09%09%09stringer.key(%22asyncOps%22).value(this.asyncOps);%0A%09%09%7D
 %0A%09%09strin

fix PutPolicy bug