/**
   * @api {get} /rest2/openrosa/:studyOID/downloadMedia Download media
   * @apiName getMediaFile
   * @apiPermission admin
   * @apiVersion 1.0.0
   * @apiParam {String} studyOID Study Oid.
   * @apiGroup Form
   * @apiDescription Downloads media associated with a form, including images and video.
   */
  @GET
  @Path("/{studyOID}/downloadMedia")
  public Response getMediaFile(
      @Context HttpServletRequest request,
      @Context HttpServletResponse response,
      @PathParam("studyOID") String studyOID,
      @QueryParam("crfVersionMediaId") String crfVersionMediaId,
      @RequestHeader("Authorization") String authorization,
      @Context ServletContext context)
      throws Exception {
    if (!mayProceedPreview(studyOID)) return null;

    CrfVersionMediaDao mediaDao =
        (CrfVersionMediaDao)
            SpringServletAccess.getApplicationContext(context).getBean("crfVersionMediaDao");
    CrfVersionMedia media = mediaDao.findById(Integer.valueOf(crfVersionMediaId));

    File image = new File(media.getPath() + media.getName());
    FileInputStream fis = new FileInputStream(image);
    StreamingOutput stream = new MediaStreamingOutput(fis);
    return Response.ok(stream).build();
  }
  /**
   * @api {get} /rest2/openrosa/:studyOID/manifest Get Form Manifest
   * @apiName getManifest
   * @apiPermission admin
   * @apiVersion 1.0.0
   * @apiParam {String} studyOID Study Oid.
   * @apiGroup Form
   * @apiDescription Gets additional information on a particular Form, including links to associated
   *     media.
   */
  @GET
  @Path("/{studyOID}/manifest")
  @Produces(MediaType.TEXT_XML)
  public String getManifest(
      @Context HttpServletRequest request,
      @Context HttpServletResponse response,
      @PathParam("studyOID") String studyOID,
      @QueryParam("formId") String crfOID,
      @RequestHeader("Authorization") String authorization,
      @Context ServletContext context)
      throws Exception {
    if (!mayProceedPreview(studyOID)) return null;

    CRFVersionDAO cVersionDao = new CRFVersionDAO(getDataSource());
    CrfVersionMediaDao mediaDao =
        (CrfVersionMediaDao)
            SpringServletAccess.getApplicationContext(context).getBean("crfVersionMediaDao");

    CRFVersionBean crfVersion = cVersionDao.findByOid(crfOID);
    List<MediaFile> mediaFiles = new ArrayList<MediaFile>();
    Manifest manifest = new Manifest();

    List<CrfVersionMedia> mediaList = mediaDao.findByCrfVersionId(crfVersion.getId());
    if (mediaList != null && mediaList.size() > 0) {
      for (CrfVersionMedia media : mediaList) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(new Date());
        String urlBase =
            getCoreResources().getDataInfo().getProperty("sysURL").split("/MainMenu")[0];

        MediaFile mediaFile = new MediaFile();
        mediaFile.setFilename(media.getName());
        mediaFile.setHash(DigestUtils.md5Hex(String.valueOf(cal.getTimeInMillis())));
        mediaFile.setDownloadUrl(
            urlBase
                + "/rest2/openrosa/"
                + studyOID
                + "/downloadMedia?crfVersionMediaId="
                + media.getCrfVersionMediaId());
        manifest.add(mediaFile);
      }
    }
    try {
      // Create the XML manifest using a Castor mapping file.
      XMLContext xmlContext = new XMLContext();
      Mapping mapping = xmlContext.createMapping();
      mapping.loadMapping(getCoreResources().getURL("openRosaManifestMapping.xml"));
      xmlContext.addMapping(mapping);

      Marshaller marshaller = xmlContext.createMarshaller();
      StringWriter writer = new StringWriter();
      marshaller.setWriter(writer);
      marshaller.marshal(manifest);

      // Set response headers
      Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("GMT"));
      Date currentDate = new Date();
      cal.setTime(currentDate);
      SimpleDateFormat format = new SimpleDateFormat("E, dd MMM yyyy HH:mm:ss zz");
      format.setCalendar(cal);
      response.setHeader("Content-Type", "text/xml; charset=UTF-8");
      response.setHeader("Date", format.format(currentDate));
      response.setHeader("X-OpenRosa-Version", "1.0");
      return writer.toString();
    } catch (Exception e) {
      LOGGER.error(e.getMessage());
      LOGGER.error(ExceptionUtils.getStackTrace(e));
      return "<Error>" + e.getMessage() + "</Error>";
    }
  }
  /**
   * @api {get} /rest2/openrosa/:studyOID/formList Get Form List
   * @apiName getFormList
   * @apiPermission admin
   * @apiVersion 1.0.0
   * @apiParam {String} studyOID Study Oid.
   * @apiGroup Form
   * @apiDescription Retrieves a listing of the available OpenClinica forms.
   * @apiParamExample {json} Request-Example: { "studyOid": "S_SAMPLTE", }
   * @apiSuccessExample {xml} Success-Response: HTTP/1.1 200 OK { <xforms
   *     xmlns="http://openrosa.org/xforms/xformsList"> <xform> <formID>F_FIRSTFORM_1</formID>
   *     <name>First Form</name> <majorMinorVersion>1</majorMinorVersion> <version>1</version>
   *     <hash>8678370cd92814d4e3216d58d821403f</hash>
   *     <downloadUrl>http://oc1.openclinica.com/OpenClinica-web/rest2/openrosa/S_SAMPLTE/formXml?
   *     formId=F_FIRSTFORM_1</downloadUrl> </xform> <xform> <formID>F_SECONDFORM_1</formID>
   *     <name>Second Form</name> <majorMinorVersion>1</majorMinorVersion> <version>1</version>
   *     <hash>7ee60d1c6516b730bbe9bdbd7cad942f</hash>
   *     <downloadUrl>http://oc1.openclinica.com/OpenClinica-web/rest2/openrosa/S_SAMPLTE/formXml?
   *     formId=F_SECONDFORM_1</downloadUrl> </xform> </xforms>
   */
  @GET
  @Path("/{studyOID}/formList")
  @Produces(MediaType.TEXT_XML)
  public String getFormList(
      @Context HttpServletRequest request,
      @Context HttpServletResponse response,
      @PathParam("studyOID") String studyOID,
      @QueryParam("formID") String crfOID,
      @RequestHeader("Authorization") String authorization,
      @Context ServletContext context)
      throws Exception {
    if (!mayProceedPreview(studyOID)) return null;

    StudyDAO sdao = new StudyDAO(getDataSource());
    StudyBean study = sdao.findByOid(studyOID);

    CRFDAO cdao = new CRFDAO(getDataSource());
    Collection<CRFBean> crfs = cdao.findAll();

    CRFVersionDAO cVersionDao = new CRFVersionDAO(getDataSource());
    Collection<CRFVersionBean> crfVersions = cVersionDao.findAll();

    CrfVersionMediaDao mediaDao =
        (CrfVersionMediaDao)
            SpringServletAccess.getApplicationContext(context).getBean("crfVersionMediaDao");

    try {
      XFormList formList = new XFormList();
      for (CRFBean crf : crfs) {
        for (CRFVersionBean version : crfVersions) {
          if (version.getCrfId() == crf.getId()) {
            XForm form = new XForm(crf, version);
            // TODO: Need to generate hash based on contents of
            // XForm. Will be done in a later story.
            // TODO: For now all XForms get a date based hash to
            // trick Enketo into always downloading
            // TODO: them.
            Calendar cal = Calendar.getInstance();
            cal.setTime(new Date());
            form.setHash(DigestUtils.md5Hex(String.valueOf(cal.getTimeInMillis())));

            String urlBase =
                getCoreResources().getDataInfo().getProperty("sysURL").split("/MainMenu")[0];
            form.setDownloadURL(
                urlBase + "/rest2/openrosa/" + studyOID + "/formXml?formId=" + version.getOid());

            List<CrfVersionMedia> mediaList = mediaDao.findByCrfVersionId(version.getId());
            if (mediaList != null && mediaList.size() > 0) {
              form.setManifestURL(
                  urlBase + "/rest2/openrosa/" + studyOID + "/manifest?formId=" + version.getOid());
            }
            formList.add(form);
          }
        }
      }

      // Create the XML formList using a Castor mapping file.
      XMLContext xmlContext = new XMLContext();
      Mapping mapping = xmlContext.createMapping();
      mapping.loadMapping(getCoreResources().getURL("openRosaFormListMapping.xml"));
      xmlContext.addMapping(mapping);

      Marshaller marshaller = xmlContext.createMarshaller();
      StringWriter writer = new StringWriter();
      marshaller.setWriter(writer);
      marshaller.marshal(formList);

      // Set response headers
      Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("GMT"));
      Date currentDate = new Date();
      cal.setTime(currentDate);
      SimpleDateFormat format = new SimpleDateFormat("E, dd MMM yyyy HH:mm:ss zz");
      format.setCalendar(cal);
      response.setHeader("Content-Type", "text/xml; charset=UTF-8");
      response.setHeader("Date", format.format(currentDate));
      response.setHeader("X-OpenRosa-Version", "1.0");
      return writer.toString();
    } catch (Exception e) {
      LOGGER.error(e.getMessage());
      LOGGER.error(ExceptionUtils.getStackTrace(e));
      return "<Error>" + e.getMessage() + "</Error>";
    }
  }