/**
   * (non-javadoc)
   *
   * @see CommunicationsClientConnection#registerComponentForCommunication(NetworkServiceType,
   *     PlatformComponentProfile)
   */
  @Override
  public void registerComponentForCommunication(
      NetworkServiceType networkServiceNetworkServiceTypeApplicant,
      PlatformComponentProfile platformComponentProfile)
      throws CantRegisterComponentException {

    try {

      System.out.println(
          "WsCommunicationsCloudClientConnection - registerComponentForCommunication");

      /*
       * Validate parameter
       */
      if (platformComponentProfile == null) {

        throw new IllegalArgumentException(
            "The platformComponentProfile is required, can not be null");
      }

      Gson gson = new Gson();
      JsonObject jsonObject = new JsonObject();
      jsonObject.addProperty(
          JsonAttNamesConstants.NETWORK_SERVICE_TYPE,
          networkServiceNetworkServiceTypeApplicant.toString());
      jsonObject.addProperty(
          JsonAttNamesConstants.PROFILE_TO_REGISTER, platformComponentProfile.toJson());

      /*
       * Construct a fermat packet whit the PlatformComponentProfile
       */
      FermatPacket fermatPacket =
          FermatPacketCommunicationFactory.constructFermatPacketEncryptedAndSinged(
              wsCommunicationsCloudClientChannel.getServerIdentity(), // Destination
              wsCommunicationsCloudClientChannel.getClientIdentity().getPublicKey(), // Sender
              gson.toJson(jsonObject), // Message Content
              FermatPacketType.COMPONENT_REGISTRATION_REQUEST, // Packet type
              wsCommunicationsCloudClientChannel
                  .getClientIdentity()
                  .getPrivateKey()); // Sender private key

      String fermatPacketEncode = FermatPacketEncoder.encode(fermatPacket);

      /*
       * Send the encode packet to the server
       */
      wsCommunicationsCloudClientChannel.send(fermatPacketEncode);

    } catch (Exception e) {

      CantRegisterComponentException pluginStartException =
          new CantRegisterComponentException(
              CantRegisterComponentException.DEFAULT_MESSAGE,
              e,
              e.getLocalizedMessage(),
              e.getLocalizedMessage());
      throw pluginStartException;
    }
  }
  /**
   * (non-javadoc)
   *
   * @see CommunicationsClientConnection#requestListComponentRegistered(PlatformComponentProfile,
   *     DiscoveryQueryParameters)
   */
  @Override
  public void requestListComponentRegistered(
      PlatformComponentProfile networkServiceApplicant,
      DiscoveryQueryParameters discoveryQueryParameters)
      throws CantRequestListException {

    try {

      System.out.println("WsCommunicationsCloudClientConnection - requestListComponentRegistered");

      /*
       * Validate parameter
       */
      if (discoveryQueryParameters == null) {

        throw new IllegalArgumentException(
            "The discoveryQueryParameters is required, can not be null");
      }

      Gson gson = new Gson();
      JsonObject jsonObject = new JsonObject();
      jsonObject.addProperty(
          JsonAttNamesConstants.NETWORK_SERVICE_TYPE,
          networkServiceApplicant.getNetworkServiceType().toString());
      jsonObject.addProperty(
          JsonAttNamesConstants.DISCOVERY_PARAM, discoveryQueryParameters.toJson());

      /*
       * Construct a fermat packet whit the filters
       */
      FermatPacket fermatPacketRespond =
          FermatPacketCommunicationFactory.constructFermatPacketEncryptedAndSinged(
              wsCommunicationsCloudClientChannel.getServerIdentity(), // Destination
              wsCommunicationsCloudClientChannel.getClientIdentity().getPublicKey(), // Sender
              gson.toJson(jsonObject), // Message Content
              FermatPacketType.REQUEST_LIST_COMPONENT_REGISTERED, // Packet type
              wsCommunicationsCloudClientChannel
                  .getClientIdentity()
                  .getPrivateKey()); // Sender private key

      /*
       * Send the encode packet to the server
       */
      wsCommunicationsCloudClientChannel.send(FermatPacketEncoder.encode(fermatPacketRespond));

    } catch (Exception e) {

      CantRequestListException pluginStartException =
          new CantRequestListException(
              CantRequestListException.DEFAULT_MESSAGE,
              e,
              e.getLocalizedMessage(),
              e.getLocalizedMessage());
      throw pluginStartException;
    }
  }
  /**
   * (non-javadoc)
   *
   * @see CommunicationsClientConnection#requestDiscoveryVpnConnection(PlatformComponentProfile,
   *     PlatformComponentProfile, PlatformComponentProfile)
   */
  @Override
  public void requestDiscoveryVpnConnection(
      PlatformComponentProfile applicantParticipant,
      PlatformComponentProfile applicantNetworkService,
      PlatformComponentProfile remoteParticipant)
      throws CantEstablishConnectionException {

    try {

      System.out.println("WsCommunicationsCloudClientConnection - requestDiscoveryVpnConnection");

      /*
       * Validate parameter
       */
      if (applicantParticipant == null
          || applicantNetworkService == null
          || remoteParticipant == null) {

        throw new IllegalArgumentException("All parameters are required, can not be null");
      }

      /*
       * Validate are the  type NETWORK_SERVICE
       */
      if (applicantNetworkService.getPlatformComponentType()
          != PlatformComponentType.NETWORK_SERVICE) {
        throw new IllegalArgumentException(
            "All the PlatformComponentProfile has to be NETWORK_SERVICE ");
      }

      /*
       * Construct the json object
       */
      Gson gson = new Gson();
      JsonObject packetContent = new JsonObject();
      packetContent.addProperty(
          JsonAttNamesConstants.APPLICANT_PARTICIPANT_VPN, applicantParticipant.toJson());
      packetContent.addProperty(
          JsonAttNamesConstants.APPLICANT_PARTICIPANT_NS_VPN, applicantNetworkService.toJson());
      packetContent.addProperty(
          JsonAttNamesConstants.REMOTE_PARTICIPANT_VPN, remoteParticipant.toJson());

      /*
       * Convert to json representation
       */
      String packetContentJson = gson.toJson(packetContent);

      /*
       * Construct a fermat packet whit the request
       */
      FermatPacket fermatPacketRespond =
          FermatPacketCommunicationFactory.constructFermatPacketEncryptedAndSinged(
              wsCommunicationsCloudClientChannel.getServerIdentity(), // Destination
              wsCommunicationsCloudClientChannel.getClientIdentity().getPublicKey(), // Sender
              packetContentJson, // Message Content
              FermatPacketType.DISCOVERY_COMPONENT_CONNECTION_REQUEST, // Packet type
              wsCommunicationsCloudClientChannel
                  .getClientIdentity()
                  .getPrivateKey()); // Sender private key
      /*
       * Send the encode packet to the server
       */
      wsCommunicationsCloudClientChannel.send(FermatPacketEncoder.encode(fermatPacketRespond));

    } catch (Exception e) {

      CantEstablishConnectionException pluginStartException =
          new CantEstablishConnectionException(
              CantEstablishConnectionException.DEFAULT_MESSAGE,
              e,
              e.getLocalizedMessage(),
              e.getLocalizedMessage());
      throw pluginStartException;
    }
  }
  /**
   * (non-javadoc)
   *
   * @see CommunicationsClientConnection#requestVpnConnection(PlatformComponentProfile,
   *     PlatformComponentProfile)
   */
  @Override
  public void requestVpnConnection(
      PlatformComponentProfile applicant, PlatformComponentProfile remoteDestination)
      throws CantEstablishConnectionException {

    try {

      System.out.println("WsCommunicationsCloudClientConnection - requestVpnConnection");

      /*
       * Validate parameter
       */
      if (applicant == null || remoteDestination == null) {

        throw new IllegalArgumentException("All parameters are required, can not be null");
      }

      List<PlatformComponentProfile> participants = new ArrayList();
      participants.add(applicant);
      participants.add(remoteDestination);

      /** Validate all are the same type and NETWORK_SERVICE */
      for (PlatformComponentProfile participant : participants) {

        if (participant.getPlatformComponentType() != PlatformComponentType.NETWORK_SERVICE) {
          throw new IllegalArgumentException(
              "All the PlatformComponentProfile has to be NETWORK_SERVICE ");
        }

        if (participant.getNetworkServiceType() != applicant.getNetworkServiceType()) {
          throw new IllegalArgumentException(
              "All the PlatformComponentProfile has to be the same type of network service type ");
        }
      }

      /*
       * Construct the json object
       */
      Gson gson = new Gson();

      /*
       * Convert to json representation
       */
      String jsonListRepresentation =
          gson.toJson(
              participants,
              new TypeToken<List<PlatformComponentProfileCommunication>>() {}.getType());

      /*
       * Construct a fermat packet whit the request
       */
      FermatPacket fermatPacketRespond =
          FermatPacketCommunicationFactory.constructFermatPacketEncryptedAndSinged(
              wsCommunicationsCloudClientChannel.getServerIdentity(), // Destination
              wsCommunicationsCloudClientChannel.getClientIdentity().getPublicKey(), // Sender
              jsonListRepresentation, // Message Content
              FermatPacketType.COMPONENT_CONNECTION_REQUEST, // Packet type
              wsCommunicationsCloudClientChannel
                  .getClientIdentity()
                  .getPrivateKey()); // Sender private key
      /*
       * Send the encode packet to the server
       */
      wsCommunicationsCloudClientChannel.send(FermatPacketEncoder.encode(fermatPacketRespond));

    } catch (Exception e) {

      CantEstablishConnectionException pluginStartException =
          new CantEstablishConnectionException(
              CantEstablishConnectionException.DEFAULT_MESSAGE,
              e,
              e.getLocalizedMessage(),
              e.getLocalizedMessage());
      throw pluginStartException;
    }
  }
  /**
   * (no-javadoc)
   *
   * @see FermatTyrusPacketProcessor#processingPackage(FermatPacket)
   */
  @Override
  public void processingPackage(final FermatPacket receiveFermatPacket) {

    // System.out.println(" ---------------------------------------------------------------------
    // ");
    // System.out.println("ServerHandshakeRespondTyrusPacketProcessor - processingPackage");

    /* -----------------------------------------------------------------------------------------
     * IMPORTANT: This Message Content of this packet come encrypted with the temporal identity public key
     * and contain the server identity whit the communications cloud client that
     * have to use to talk with the server.
     * -----------------------------------------------------------------------------------------
     */

    /*
     * Decrypt the message content
     */
    String jsonRepresentation =
        AsymmetricCryptography.decryptMessagePrivateKey(
            receiveFermatPacket.getMessageContent(),
            getWsCommunicationsTyrusCloudClientChannel().getTemporalIdentity().getPrivateKey());

    /*
     * Construct the json object
     */
    JsonParser parser = new JsonParser();
    JsonObject serverIdentity = parser.parse(jsonRepresentation).getAsJsonObject();

    /*
     * Get the server identity and set into the communication cloud client
     */
    getWsCommunicationsTyrusCloudClientChannel()
        .setServerIdentity(serverIdentity.get(JsonAttNamesConstants.SERVER_IDENTITY).getAsString());

    // System.out.println("ServerHandshakeRespondTyrusPacketProcessor - ServerIdentity = "+
    // getWsCommunicationsTyrusCloudClientChannel().getServerIdentity());

    /*
     * Construct a Communications Cloud Client Profile for this component and send and fermat packet type FermatPacketType.COMPONENT_REGISTRATION_REQUEST
     */

    HardwareManager hardwareManager =
        getWsCommunicationsTyrusCloudClientChannel().getHardwareManager();
    CloudClientExtraData cloudClientExtraData = null;
    if (hardwareManager != null) {
      cloudClientExtraData =
          new CloudClientExtraData(
              hardwareManager.getOperativeSystem(),
              hardwareManager.getBoard(),
              hardwareManager.getBrand(),
              hardwareManager.getDevice());
    }

    PlatformComponentProfile communicationsCloudClientProfile =
        getWsCommunicationsTyrusCloudClientChannel()
            .getWsCommunicationsTyrusCloudClientConnection()
            .constructPlatformComponentProfileFactory(
                getWsCommunicationsTyrusCloudClientChannel().getClientIdentity().getPublicKey(),
                "WsCommunicationsCloudClientChannel",
                "Web Socket Communications Cloud Client",
                NetworkServiceType.UNDEFINED,
                PlatformComponentType.COMMUNICATION_CLOUD_CLIENT,
                (hardwareManager != null) ? new Gson().toJson(cloudClientExtraData) : null);
    getWsCommunicationsTyrusCloudClientChannel()
        .setPlatformComponentProfile(communicationsCloudClientProfile);

    /* ------------------------------------
     * IMPORTANT: At this moment the server only
     * know the temporal identity of the client
     * the packet has construct with this identity
     * --------------------------------------
     */

    /*
     * Construc the jsonObject
     */
    Gson gson = new Gson();
    JsonObject jsonObject = new JsonObject();
    jsonObject.addProperty(
        JsonAttNamesConstants.NETWORK_SERVICE_TYPE, NetworkServiceType.UNDEFINED.toString());
    jsonObject.addProperty(
        JsonAttNamesConstants.PROFILE_TO_REGISTER, communicationsCloudClientProfile.toJson());

    /*
     * Construct a fermat packet whit the server identity
     */
    FermatPacket fermatPacketRespond =
        FermatPacketCommunicationFactory.constructFermatPacketEncryptedAndSinged(
            getWsCommunicationsTyrusCloudClientChannel().getServerIdentity(), // Destination
            getWsCommunicationsTyrusCloudClientChannel()
                .getTemporalIdentity()
                .getPublicKey(), // Sender
            gson.toJson(jsonObject), // Message Content
            FermatPacketType.COMPONENT_REGISTRATION_REQUEST, // Packet type
            getWsCommunicationsTyrusCloudClientChannel()
                .getTemporalIdentity()
                .getPrivateKey()); // Sender private key

    /*
     * Send the encode packet to the server
     */
    getWsCommunicationsTyrusCloudClientChannel()
        .sendMessage(FermatPacketEncoder.encode(fermatPacketRespond));
  }