
import java.util.logging.Logger;
import java.io.PrintWriter;

import vo.parameter.*;

public final class XmlSerializer
{
   private static final Logger LOGGER = Logger.getLogger(XmlSerializer.class.getName());

   private XmlSerializer() {} // disables instatiation

  public static void serializeToLegacyCutResult(PrintWriter writer, String charEncoding,
        CutResult cutResult, String accessUrl,
        String id, Pos pos, Band band, Time time, Pol pol, String pixels, boolean countNullValues,
         boolean showDuration, long startTime_msec)
  {
     LOGGER.fine("trace serialize for accessUrl: " + ((accessUrl==null)? "null":accessUrl));

     writer.println("<?xml version=\"1.0\" encoding=\"" + charEncoding + "\" standalone=\"yes\"?>");
     writer.println("<results>");
     writer.println("<description> SODA cutout from: " + (id==null?"null":id) + " </description>");

     Coord coord   = new Coord(pos, band, time, pol, pixels);// pixels-input
     Inputs inputs = new Inputs(id, coord, countNullValues);

     serialize(writer, inputs);

     // pixels-output
     if(cutResult.pixels != null)
        writer.println("<CUT> " + cutResult.pixels + " </CUT>");

     if(accessUrl != null) 
     {
        writer.println("<URL> " + accessUrl + " </URL>");
        writer.println("<cutoutSize> " + cutResult.fileSize + " </cutoutSize>");
     }

     if(cutResult.nullValueCount != null)
        writer.println(serialize(cutResult.nullValueCount ));

     writer.println("<msg> " + Version.asString + " </msg>");

     writer.println("<DatacubeCount> 1 </DatacubeCount>");

     if(showDuration)
        writer.println("<duration unit=\"msec\">"+(System.currentTimeMillis() - startTime_msec)+"</duration>");

     writer.println("</results>");
  }


  public static void serializeToLegacyCutResult(PrintWriter writer, String charEncoding,
        MCutResult result, String accessUrl,
        //String id, Pos pos, Band band, Time time, Pol pol, String pixels, boolean countNullValues,
         boolean showDuration, long startTime_msec)
  {
     LOGGER.fine("trace serialize for accessUrl: " + ((accessUrl==null)? "null":accessUrl));

     writer.println("<?xml version=\"1.0\" encoding=\"" + charEncoding + "\" standalone=\"yes\"?>");
     writer.println("<results>");
     writer.println("<description> SODA mcutout </description>");

     //Coord coord   = new Coord(pos, band, time, pol, pixels);// pixels-input
     //Inputs inputs = new Inputs(id, null, false);//countNullValues);
     //serialize(writer, inputs);

     // pixels-output
//     if(cutResult.pixels != null)
//        writer.println("<CUT> " + result.pixels + " </CUT>");

     if(accessUrl != null) 
     {
        writer.println("<URL> " + accessUrl + " </URL>");
        writer.println("<cutoutSize> " + result.fileSize + " </cutoutSize>");
     }


     if(result.cutResArr != null)
     {
        writer.println("<URL_CONTENT> ");
        for(MCutResult.Cut cut : result.cutResArr)
        {
           writer.println("<ITEM>");
           writer.println("<INDEX> " + cut.index + " </INDEX>");
           writer.println("<CONTENT_CODE> " + cut.contentType.toString() + " </CONTENT_CODE>");
           writer.println("<CONTENT> " + cut.content + " </CONTENT>");
           writer.println("</ITEM>");
        }
        writer.println("</URL_CONTENT>");
     }

     //     if(cutResult.nullValueCount != null)
     //        writer.println(serialize(cutResult.nullValueCount ));

     writer.println("<msg> " + Version.asString + " </msg>");

     //     writer.println("<DatacubeCount> " + result.cuts.length  + " </DatacubeCount>");

     if(showDuration)
        writer.println("<duration unit=\"msec\">"+(System.currentTimeMillis() - startTime_msec)+"</duration>");

     writer.println("</results>");
  }




  public static String serialize(NullValueCount nullVals)
  {
     StringBuilder xml = new StringBuilder();
     xml.append("<nullValues>");
     xml.append("<description> Undefined pixel count </description>");
     xml.append("<percent>"    + nullVals.percent + "</percent>");
     xml.append("<pixels>");
     xml.append("<nullcount>"  + nullVals.nullCount + "</nullcount>");
     xml.append("<totalcount>" + nullVals.totalCount + "</totalcount>");
     xml.append("</pixels>");
     xml.append("</nullValues>");
     return xml.toString();
  }

  public static String serialize(Coord coord)
  {
     StringBuilder xml = new StringBuilder();
     xml.append("<SkySystem>"+coord.skySystem+"</SkySystem>");

     /* reconstruct VLKB-legacy param values from SODA-params */

     if(coord.shape != null)
     {
        switch(coord.shape)
        {
           case "CIRCLE" :
              xml.append("<l>"+coord.pos.circle.lon+"</l>");
              xml.append("<b>"+coord.pos.circle.lat+"</b>");
              xml.append("<r>"+coord.pos.circle.radius+"</r>");
              break;
           case "RECT"   :
              xml.append("<l>"  + String.valueOf((coord.pos.range.lon1 + coord.pos.range.lon2)/2.0) + "</l>");
              xml.append("<b>"  + String.valueOf((coord.pos.range.lat1 + coord.pos.range.lat2)/2.0) + "</b>");
              xml.append("<dl>" + String.valueOf(coord.pos.range.lon2 - coord.pos.range.lon1) + "</dl>");
              xml.append("<db>" + String.valueOf(coord.pos.range.lat2 - coord.pos.range.lat1) + "</db>");
              break;
           default:
              xml.append("<shape> unknown shape: "+ coord.shape +" </shape>");
        }
     }

     if(coord.band != null)
     {
        xml.append("<vl>"   + String.valueOf(coord.band.getMin())  +"</vl>");
        xml.append("<vu>"   + String.valueOf(coord.band.getMax())   +"</vu>");
        xml.append("<vtype>" + coord.specSystem + "</vtype>");
     }

     return xml.toString();
  }

  public static String serialize(AuthPolicy auth)
  {
     StringBuilder xml = new StringBuilder();
     xml.append("<AccessPolicy>" + auth.getAccessPolicy() + "</AccessPolicy>");
     String ug = auth.getUserGroupsAsString(" ");
     if(auth.getUserName() != null) xml.append("<UserName>" + auth.getUserName() + "</UserName>");
     if(ug            != null) xml.append("<GroupNames>" + ug + "</GroupNames>");
     return xml.toString();
  }


  public static void serialize(PrintWriter writer, Inputs inputs)
  {
     if(inputs != null)
     {
        writer.println("<input>");
        if(inputs.pubdid      != null) writer.println("<pubdid>"+inputs.pubdid+"</pubdid>");
        if(inputs.coord       != null) writer.println(serialize(inputs.coord));
        if(inputs.countNullValues)     writer.println("<nullvals> set </nullvals>");
        if(inputs.auth        != null) writer.println(serialize(inputs.auth));
        writer.println("</input>");
     }
  }

}
