package com.nifty.cloud.ncs.service.parser;

import java.text.ParseException;
import java.util.Date;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;

import com.nifty.cloud.ncs.NiftyCloudResponse;
import com.nifty.cloud.ncs.NiftyCloudServiceException;
import com.nifty.cloud.ncs.http.HttpResponse;
import com.nifty.cloud.ncs.service.CopyObjectResult;
import com.nifty.cloud.ncs.service.StorageException;
import com.nifty.cloud.ncs.util.DateUtils;

/**
 * CopyObjectの応答XML解析用クラスです。
 */
public class CopyObjectParser extends AbstractStorageResponseParser<CopyObjectResult>
{
	private static Log log = LogFactory.getLog(CopyObjectParser.class);

	public CopyObjectParser()
	{
		super();
	}

	@Override
	public NiftyCloudResponse<CopyObjectResult> parse(HttpResponse response) throws Exception
	{
		NiftyCloudResponse<CopyObjectResult> ncsResponse = super.parseMetaData(response);

		CopyObjectUnmarshaller unmarshaller = new CopyObjectUnmarshaller();
		parseXml(unmarshaller, response.getContent());
		CopyObjectResult result = unmarshaller.getResult();

		ncsResponse.setResult(result);

		return (ncsResponse);
	}

	public class CopyObjectUnmarshaller extends DefaultHandler
	{
		private CopyObjectResult result;
		private StringBuffer text = null;
		private boolean hasErrorResponse = false;
		private NiftyCloudServiceException exception = null;
		private String errorCode = null;
		private String errorMessage = null;
		private String requestId = null;

		public CopyObjectUnmarshaller()
		{
			super();
			result = new CopyObjectResult();
			text = new StringBuffer();
		}

		public CopyObjectResult getResult()
		{
			return (result);
		}

		@Override
		public void startElement(String uri, String localName, String qName,
				Attributes attributes) throws SAXException
		{
			if (localName.equals("Error")) {
				hasErrorResponse = true;
			}
		}

		@Override
		public void endElement(String uri, String localName, String qName)
				throws SAXException
		{
			if (hasErrorResponse == false) {
				if (localName.equals("ETag")) {
					result.setETag(text.toString().replace("\"", ""));
				}
				else if (localName.equals("LastModified")) {
					Date lastModified = null;
					try {
						lastModified = DateUtils.parseIso8601Date(text.toString());
					} catch (ParseException e) {
						log.warn("Unable parse LastModified.");
					}
					result.setLastModified(lastModified);
				}
			}
			// エラーレスポンスの場合
			else {
				if (localName.equals("Message")) {
					errorMessage = text.toString();
				}
				else if (localName.equals("Code")) {
					errorCode = text.toString();
				}
				else if (localName.equals("RequestId")) {
					requestId = text.toString();
				}
			}
			text = new StringBuffer();
		}

		@Override
		public void endDocument() throws SAXException
		{
			if (hasErrorResponse) {
				exception = new StorageException(errorMessage);
				exception.setErrorCode(errorCode);
				exception.setRequestId(requestId);
				result.setException(exception);
			}
		}

		@Override
		public void characters(char[] ch, int start, int length)
				throws SAXException
		{
			text.append(ch, start, length);
		}
	}
}
