package org.gcube.nlphub;

//import static org.gcube.common.authorization.client.Constants.authorizationService;

import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;

import javax.servlet.ServletException;
import javax.servlet.annotation.MultipartConfig;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.Part;

import org.apache.log4j.Logger;
import org.gcube.nlphub.legacy.Constants;
import org.gcube.nlphub.legacy.JsonManager;
import org.gcube.nlphub.legacy.NlpHubException;
import org.gcube.nlphub.nlp.NLpLanguageRecognizer;
import org.gcube.nlphub.nlp.NlpUtils;
import org.gcube.nlphub.workspace.WorkspaceManager;

/**
 * Servlet implementation class NLPUploader
 */
// @WebServlet("/NLPUploader")
@WebServlet(asyncSupported = true, name = "NLPUploader", urlPatterns = { "/nlphub-uploader-servlet" })
@MultipartConfig
public class NLPUploader extends HttpServlet {
	private static final long serialVersionUID = 1L;
	private Logger logger = Logger.getLogger(NLPUploader.class.getSimpleName());
	private boolean devMode = true;
	private String token; // = "df2cc5f5-63ee-48c1-b2a6-1210030c57b8-843339462";
	private WorkspaceManager ws;

	/**
	 * @see HttpServlet#HttpServlet()
	 */
	public NLPUploader() {
		super();
		// TODO Auto-generated constructor stub
	}

	/**
	 * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse
	 *      response)
	 */
	protected void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		doWork(request, response);
	}

	/**
	 * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse
	 *      response)
	 */
	protected void doPost(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		token = Constants.getToken(request, devMode);
		doWork(request, response);
	}

	private void doWork(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		ws = new WorkspaceManager();
		response.setContentType("application/json;charset=UTF-8");
		if (request.getParameter("freetext") == null)
			handleFileUpload(request, response);
		else
			handleFreeText(request, response);
	}

	private void handleFreeText(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		String freeText = request.getParameter("freetext");
		freeText = NlpUtils.replaceDirtyCharacters(freeText);

		byte[] content = freeText.getBytes("UTF-8");
		String fileName = generateFileName();
		PrintWriter writer = response.getWriter();
		try {
			if (!ws.uploadFile(content, fileName, Constants.DEFAULT_DESCRIPTION, token)) {
				writer.println(new JsonManager().getErrorJsonResponse(
						"Error uploading file. A file called '" + fileName + "' is already in the workspace?"));
				return;
			}
			String link = ws.getPublicLink(fileName, token);
			if(request.getParameter("getlang") != null) {
				String sentence = NlpUtils.getLanguageRecognizerDigest(new String(content));
				logger.info(sentence);
				try {
					NLpLanguageRecognizer.run(request.getParameter("dataminer"), sentence, token, link, response);
				} catch (NlpHubException ex) {
					writer.println(new JsonManager().getSuccessJsonResponse(Constants.UNAVAILABLE, link));
				}				
			}
			else writer.println(new JsonManager().getSuccessJsonResponse("" + link));
		} catch (Exception x) {
			x.printStackTrace();
			logger.error(x.getClass().getName() + ": " + x.getLocalizedMessage());
			writer.println(new JsonManager().getErrorJsonResponse(x.getLocalizedMessage()));
		}
	}

	private void handleFileUpload(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		int contentLength = request.getContentLength();

		Part filePart = request.getPart("mytxtfile");

		String fileName = getFileName(filePart);

		PrintWriter writer = response.getWriter();
		// allocate a buffer of request size
		byte[] buffer = new byte[contentLength];
		byte[] bufferedContent;
		try {
			InputStream fileContent = filePart.getInputStream();
			int offset = 0, len = 256, byteRead = 0;
			byte[] readBuffer = new byte[len];
			while (byteRead > -1) {
				byteRead = fileContent.read(readBuffer, 0, len);
				if (byteRead > 0) {
					System.arraycopy(readBuffer, 0, buffer, offset, byteRead);
					offset += byteRead;
				}
			}

			if (offset < contentLength) {
				bufferedContent = new byte[offset];
				System.arraycopy(buffer, 0, bufferedContent, 0, offset);
			} else
				bufferedContent = buffer;

			String stringContent = new String(bufferedContent);
			stringContent = NlpUtils.replaceDirtyCharacters(stringContent);

			ws.deleteFile(fileName, token);

			if (!ws.uploadFile(stringContent.getBytes(), fileName, Constants.DEFAULT_DESCRIPTION, token)) {
				writer.println(new JsonManager().getErrorJsonResponse(
						"Error uploading file. A file called '" + fileName + "' is already in the workspace?"));
				return;
			}

			String link = ws.getPublicLink(fileName, token);
			String sentence = NlpUtils.getLanguageRecognizerDigest(stringContent);
			logger.info(sentence);
			try {
				NLpLanguageRecognizer.run(request.getParameter("dataminer"), sentence, token, link, response);
			} catch (NlpHubException ex) {
				writer.println(new JsonManager().getSuccessJsonResponse(Constants.UNAVAILABLE, link));
			}
			// writer.println(new JsonManager().getSuccessJsonResponse("" +
			// link));
		} catch (Exception x) {
			x.printStackTrace();
			logger.error(x.getClass().getName() + ": " + x.getLocalizedMessage());
			writer.println(new JsonManager().getErrorJsonResponse(x.getLocalizedMessage()));
		}

	}

	private String getFileName(Part part) {
		String partHeader = part.getHeader("content-disposition");
		logger.debug("Part Header: " + partHeader);
		for (String content : part.getHeader("content-disposition").split(";")) {
			if (content.trim().startsWith("filename")) {
				return content.substring(content.indexOf('=') + 1).trim().replace("\"", "");
			}
		}
		return null;
	}

	private String generateFileName() {
		long now = System.currentTimeMillis();
		return "auto-nlp-" + now;
	}
}
