package simplecloud.storage.providers.amazon;

import java.io.IOException;
import java.io.StringReader;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathExpressionException;
import javax.xml.xpath.XPathFactory;

import libcloud.exceptions.InvalidCredsException;

import org.w3c.dom.Document;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;

import base.connection.ResponseHandler;
import base.interfaces.IResponse;

/*
 * Custom handles responses from S3.
 */
public class S3Handler extends ResponseHandler {

	public S3Handler(IResponse response) {
		super(response);
	}
	
	protected void parseBody() {
		object = response.getItem();
	}
	
	protected String parseError() {
		try {
			// Parse errors
			DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
			DocumentBuilder db = dbf.newDocumentBuilder();
			Document doc = db.parse(new InputSource(new StringReader(response.getBody())));
			XPath xpath = XPathFactory.newInstance().newXPath();
			NodeList errors = (NodeList)xpath.evaluate("/Error", doc.getDocumentElement(), XPathConstants.NODESET);
			
			// Process errors
			StringBuffer sb = new StringBuffer();
			for (int i = 0; i < errors.getLength(); i++) {
				String error = (String)xpath.evaluate("Code", errors.item(i));
				String message = (String)xpath.evaluate("Message", errors.item(i));
				if (error.equals("InvalidClientTokenId")) {
					throw new InvalidCredsException(response.getStatus() + " " + error + ": " + message);
				} else if (error.equals("SignatureDoesNotMatch")) {
					throw new InvalidCredsException(response.getStatus() + " " + error + ": " + message);
				} else if (error.equals("AuthFailure")) {
					throw new InvalidCredsException(response.getStatus() + " " + error + ": " + message);
				} else if (error.equals("OptInRequired")) {
					throw new InvalidCredsException(response.getStatus() + " " + error + ": " + message);
				} else {
					sb.append(response.getStatus() + " " + error + ": " + message + '\n');
				}
			}
			return sb.toString().trim();
		} catch (ParserConfigurationException e) {
			e.printStackTrace();
		} catch (SAXException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} catch (XPathExpressionException e) {
			e.printStackTrace();
		}
		return super.parseError();
	}
}
