/** Initialize the name resolver, the epoch and the object name. */
  @Override
  public final void doInit() {
    super.doInit();
    Validation validationForm =
        new InputsValidation(getRequest().getResourceRef().getQueryAsForm().getValuesMap());
    validationForm = new NotNullAndNotEmptyValidation(validationForm, "nameResolver");
    validationForm = new NotNullAndNotEmptyValidation(validationForm, "epoch");
    final StatusValidation statusValidationForm = validationForm.validate();
    if (statusValidationForm.isValid()) {
      final Map<String, String> userInputParameters = validationForm.getMap();
      this.nameResolver = userInputParameters.get("nameResolver");
      this.epoch = userInputParameters.get("epoch");
    } else {
      this.nameResolver = getParameterValue("nameResolver");
      this.epoch = getParameterValue("epoch");
    }

    if (!getRequest().getMethod().equals(Method.OPTIONS)) {
      Validation validationAttributes = new InputsAttributesValidation(getRequestAttributes());
      validationAttributes = new NotNullAndNotEmptyValidation(validationAttributes, "objectName");
      validationAttributes = new NotNullAndNotEmptyValidation(validationAttributes, "coordSystem");
      final StatusValidation status = validationAttributes.validate();
      if (status.isValid()) {
        final Map<String, String> requestInputs = validationAttributes.getMap();
        this.objectName = Reference.decode(requestInputs.get("objectName"));
        final String coordinatesSystem = requestInputs.get("coordSystem");
        if (coordinatesSystem.equalsIgnoreCase(CoordinateSystem.EQUATORIAL.name())) {
          this.coordSystem = CoordinateSystem.EQUATORIAL;
        } else if (coordinatesSystem.equalsIgnoreCase(CoordinateSystem.GALACTIC.name())) {
          this.coordSystem = CoordinateSystem.GALACTIC;
        } else {
          LOG.log(Level.WARNING, "Name resolver service - Wrong parameter: {0}", coordinatesSystem);
          throw new ResourceException(
              Status.CLIENT_ERROR_BAD_REQUEST,
              coordinatesSystem + " must be either EQUATORIAL or GALACTIC");
        }
      } else {
        LOG.log(Level.WARNING, "Name resolver service - Wrong parameters");
        throw new ResourceException(Status.CLIENT_ERROR_BAD_REQUEST, "Check your input parameters");
      }
    }
  }
  /**
   * Descibes the GET method in WADL.
   *
   * @param info information
   */
  @Override
  protected final void describeGet(final MethodInfo info) {
    this.addInfo(info);
    info.setIdentifier("NameResolver");
    info.setDocumentation("Get the object's coordinates from its name and time for planets.");

    // objecName parameter
    final List<ParameterInfo> parametersInfo = new ArrayList<ParameterInfo>();
    parametersInfo.add(
        new ParameterInfo(
            "objectName", true, "String", ParameterStyle.TEMPLATE, "Object name to resolve"));

    // reference frame parameter
    final ParameterInfo paramCoordSys =
        new ParameterInfo(
            "coordSystem",
            true,
            "String",
            ParameterStyle.TEMPLATE,
            "Coordinate system in which the output is formated");
    final List<OptionInfo> coordsysOption = new ArrayList<OptionInfo>();
    final OptionInfo optionEquatorial = new OptionInfo("Equatorial system in ICRS");
    optionEquatorial.setValue(CoordinateSystem.EQUATORIAL.name());
    coordsysOption.add(optionEquatorial);
    final OptionInfo optionGalactic = new OptionInfo("Galactic system");
    optionGalactic.setValue(CoordinateSystem.GALACTIC.name());
    coordsysOption.add(optionGalactic);
    paramCoordSys.setOptions(coordsysOption);
    parametersInfo.add(paramCoordSys);

    // Name resolver parameter
    final ParameterInfo nameResolverParam =
        new ParameterInfo(
            "nameResolver", false, "String", ParameterStyle.QUERY, "The selected name resolver");
    final List<OptionInfo> nameResolverOption = new ArrayList<OptionInfo>();
    final OptionInfo optionCDS = new OptionInfo("The CDS name resolver based on SIMBAD and NED");
    optionCDS.setValue("CDS");
    nameResolverOption.add(optionCDS);
    final OptionInfo optionIAS = new OptionInfo("The IAS name resolver for Corot");
    optionIAS.setValue("IAS");
    nameResolverOption.add(optionIAS);
    nameResolverParam.setOptions(nameResolverOption);
    final OptionInfo optionIMCCE =
        new OptionInfo("The IMCEE name resolver for solar system bodies");
    optionIMCCE.setValue("IMCCE");
    nameResolverOption.add(optionIMCCE);
    nameResolverParam.setOptions(nameResolverOption);
    final OptionInfo optionAll = new OptionInfo("Query all name resolvers");
    optionAll.setValue("ALL");
    nameResolverOption.add(optionAll);
    final String nameResolverFromModel =
        this.getModel().getParameterByName("nameResolver").getValue();
    final String defaultNameResolver =
        (nameResolverFromModel != null && !nameResolverFromModel.isEmpty())
            ? nameResolverFromModel
            : "CDS";
    nameResolverParam.setDefaultValue(defaultNameResolver);
    parametersInfo.add(nameResolverParam);

    // Time frame for IMCCE
    final ParameterInfo time =
        new ParameterInfo(
            "epoch",
            false,
            "String",
            ParameterStyle.QUERY,
            "Time frame for IMCCE name resolver. See documentation from IMCCE");
    final String timeFromModel = this.getModel().getParameterByName("epoch").getValue();
    final String defaultTime =
        (timeFromModel != null && !timeFromModel.isEmpty()) ? timeFromModel : "now";
    time.setDefaultValue(defaultTime);
    parametersInfo.add(time);

    // Set all parameters
    info.getRequest().setParameters(parametersInfo);

    // Response OK
    final ResponseInfo responseOK = new ResponseInfo();
    List<RepresentationInfo> representationsInfo = new ArrayList<RepresentationInfo>();
    RepresentationInfo representationInfo = new RepresentationInfo(MediaType.APPLICATION_JSON);
    final DocumentationInfo doc = new DocumentationInfo();
    doc.setTitle("Name Resolver representation");
    doc.setTextContent(
        "<pre>{\n"
            + "totalResults: 1,\n"
            + "type: \"FeatureCollection\",\n"
            + "features: [\n"
            + "  geometry: {\n"
            + "    coordinates: [10.6847083,41.26875],\n"
            + "    type: \"Point\"\n"
            + "  },\n"
            + "properties: {\n"
            + "  crs: {\n"
            + "    type: \"name\",\n"
            + "    properties: {\n"
            + "      name: \"EQUATORIAL.ICRS\"\n"
            + "    }\n"
            + "  },\n"
            + "  credits: \"CDS\",\n"
            + "  identifier: \"CDS0\"\n"
            + "}\n"
            + "}]}</pre>");
    representationInfo.setDocumentation(doc);
    representationsInfo.add(representationInfo);
    responseOK.getRepresentations().add(representationInfo);
    responseOK.getStatuses().add(Status.SUCCESS_OK);

    // response bad request and internal error
    representationsInfo = new ArrayList<RepresentationInfo>();
    representationInfo = new RepresentationInfo(MediaType.TEXT_HTML);
    representationInfo.setDocumentation("SITools2 status error page");
    representationsInfo.add(representationInfo);

    final ResponseInfo responseError = new ResponseInfo();
    responseError.getRepresentations().add(representationInfo);
    responseError.getStatuses().add(Status.SERVER_ERROR_INTERNAL);
    responseError.setDocumentation("Unexpected error");

    final ResponseInfo responseBad = new ResponseInfo();
    responseBad.getRepresentations().add(representationInfo);
    responseBad.getStatuses().add(Status.CLIENT_ERROR_BAD_REQUEST);
    responseBad.setDocumentation(
        Status.CLIENT_ERROR_BAD_REQUEST.getDescription() + "- coordinate system is unknown");

    final ResponseInfo responseNotFound = new ResponseInfo();
    responseNotFound.getRepresentations().add(representationInfo);
    responseNotFound.getStatuses().add(Status.CLIENT_ERROR_NOT_FOUND);
    responseNotFound.setDocumentation("object not found.");

    final ResponseInfo responseUnavailable = new ResponseInfo();
    responseUnavailable.getRepresentations().add(representationInfo);
    responseUnavailable.getStatuses().add(Status.SERVER_ERROR_SERVICE_UNAVAILABLE);
    responseUnavailable.setDocumentation(Status.SERVER_ERROR_SERVICE_UNAVAILABLE.getDescription());

    // Set responses
    final List<ResponseInfo> responseInfo = new ArrayList<ResponseInfo>();
    responseInfo.add(responseOK);
    responseInfo.add(responseError);
    responseInfo.add(responseBad);
    responseInfo.add(responseUnavailable);
    responseInfo.add(responseNotFound);
    info.getResponses().addAll(responseInfo);
  }