import java.util.logging.Logger;

import java.security.Principal;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import java.io.IOException;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.BufferedReader;
import java.io.PrintWriter;

import java.util.Arrays;
import java.util.List;
import java.util.LinkedList;
import java.util.Map;
import java.util.Properties;

// for Logging/Accounting
import org.json.simple.JSONObject;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.TimeZone;

// read HTTP body
import java.util.stream.Collectors;
import org.apache.commons.io.IOUtils;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonProperty;


public class ServletMCutout extends javax.servlet.http.HttpServlet
{
   private static final Logger   LOGGER   = Logger.getLogger(ServletMCutout.class.getName());
   private static final Settings settings = Settings.getInstance();

   protected Datasets datasets = new DatasetsImpl(settings);



   public void init() throws ServletException
   {
      super.init();

      LOGGER.info("FITS : " + settings.fitsPaths.toString());
      LOGGER.info("AMQP : " + settings.amqpConn.toString());
      LOGGER.info("DB   : " + settings.dbConn.toString());

   }


   /* DALI allows GET and POST for sync services */

   protected void doGet(HttpServletRequest request, HttpServletResponse response)
       throws ServletException, IOException
   {
      processRequest(request, response);
   }

   protected void doPost(HttpServletRequest request, HttpServletResponse response)
      throws ServletException, IOException
   {
      processRequest(request, response);
   }



   protected void processRequest(HttpServletRequest request, HttpServletResponse response)
      throws ServletException, IOException
   {
            long startTime_msec = System.currentTimeMillis();
      boolean showDuration = true;

      InputStreamReader isr                  = null;

      response.setContentType("text/xml");
      try
      {
         isr    = new InputStreamReader(request.getInputStream(),"utf-8");


         BufferedReader input = new BufferedReader(isr);
         StringBuffer jsonStringBuffer = new StringBuffer();
         String line;
         while((line = input.readLine()) != null)
         {
            jsonStringBuffer.append(line);
         }
         String reqJsonString = jsonStringBuffer.toString();

         OutputStream respOutputStream = response.getOutputStream();

         MCutResult result = datasets.doMCutout(reqJsonString);

         final String contentType = "text/xml"; // FIXME
         final String respEncoding = "utf-8"; // FIXME
         if(contentType.equals("text/xml") || contentType.equals("application/xml"))
         {
            PrintWriter writer = new PrintWriter(new OutputStreamWriter(respOutputStream, respEncoding));


            String accessUrl = convertLocalPathnameToRemoteUrl(result.fileName,
                  settings.fitsPaths.cutouts(),
                  settings.fitsPaths.cutoutsUrl());

            XmlSerializer.serializeToLegacyCutResult(writer, respEncoding,
                  result, accessUrl,
                  //id, pos, band, time, pol, pixels, countNullValues,
                  showDuration, startTime_msec);


            writer.close();
         }
         else if(contentType.equals("application/tar.gz")) // FIXME mime for tgz ?
         {
            //LOGGER.info("streaming the file NOT IMPLEMENTED yet for mcutout");
            /*  
                File downloadFile = new File(cod.absCutPathname);
                FileInputStream input = new BuffereInputStream(new FileInputStream(downloadFile));
                input.transferTo(respOutputStream);
                LOGGER.info("Deleting after download: " + downloadFile.getName() );
                downloadFile.delete();
                */
         }
         else
         {
            throw new AssertionError("Unsupported contentType for output: " + contentType);
         }


      }
      catch(IOException ex)
      {
         /* FIXME find better exception */
         throw new AssertionError("internal error: jsonFile.open() throws IOException:" + ex.getMessage());
      }
   }

  private String convertLocalPathnameToRemoteUrl(String localPathname,
         String FITScutpath, String FITSRemoteUrlCutouts)
   {   
      LOGGER.info("trace " + localPathname);
      String fileName = localPathname.replaceAll(FITScutpath + "/", "");
      LOGGER.info("local filename: " + fileName);
      String remotefname = FITSRemoteUrlCutouts + "/" + fileName;
      LOGGER.info("remote url    : " + remotefname);
      return remotefname;
   }   


}