/**
   * This method constructs the URLs for each of the API Endpoints called by the device agent Ex:
   * Register API, Push-Data API
   *
   * @throws AgentCoreOperationException if any error occurs at socket level whilst trying to
   *     retrieve the deviceIP of the network-interface read from the configs file
   */
  public static void initializeServerEndPoints() {
    AgentManager agentManager = AgentManager.getInstance();
    String serverSecureEndpoint = agentManager.getAgentConfigs().getHTTPS_ServerEndpoint();
    String serverUnSecureEndpoint = agentManager.getAgentConfigs().getHTTP_ServerEndpoint();
    String backEndContext = agentManager.getAgentConfigs().getControllerContext();
    String scepBackEndContext = agentManager.getAgentConfigs().getScepContext();

    String deviceControllerAPIEndpoint = serverSecureEndpoint + backEndContext;

    String deviceEnrollmentEndpoint =
        serverUnSecureEndpoint + scepBackEndContext + AgentConstants.DEVICE_ENROLLMENT_API_EP;
    agentManager.setEnrollmentEP(deviceEnrollmentEndpoint);

    String registerEndpointURL =
        deviceControllerAPIEndpoint + AgentConstants.DEVICE_REGISTER_API_EP;
    agentManager.setIpRegistrationEP(registerEndpointURL);

    String pushDataEndPointURL =
        deviceControllerAPIEndpoint + AgentConstants.DEVICE_PUSH_TEMPERATURE_API_EP;
    agentManager.setPushDataAPIEP(pushDataEndPointURL);

    log.info(
        AgentConstants.LOG_APPENDER
            + "IoT Server's Device Controller API Endpoint: "
            + deviceControllerAPIEndpoint);
    log.info(AgentConstants.LOG_APPENDER + "Device Enrollment EndPoint: " + registerEndpointURL);
    log.info(
        AgentConstants.LOG_APPENDER + "DeviceIP Registration EndPoint: " + registerEndpointURL);
    log.info(AgentConstants.LOG_APPENDER + "Push-Data API EndPoint: " + pushDataEndPointURL);
  }
  /**
   * This method reads the agent specific configurations for the device from the
   * "deviceConfigs.properties" file found at /repository/conf folder. If the properties file is not
   * found in the specified path, then the configuration values are set to the default ones in the
   * 'AgentConstants' class.
   *
   * @return an object of type 'AgentConfiguration' which contains all the necessary configuration
   *     attributes
   */
  public static AgentConfiguration readIoTServerConfigs() throws AgentCoreOperationException {
    AgentManager agentManager = AgentManager.getInstance();
    AgentConfiguration iotServerConfigs = new AgentConfiguration();
    Properties properties = new Properties();
    InputStream propertiesInputStream = null;
    String propertiesFileName = AgentConstants.AGENT_PROPERTIES_FILE_NAME;

    try {
      ClassLoader loader = AgentUtilOperations.class.getClassLoader();
      URL path = loader.getResource(propertiesFileName);
      System.out.println(path);
      String root =
          path.getPath()
              .replace("wso2-firealarm-virtual-agent.jar!/deviceConfig.properties", "")
              .replace("jar:", "")
              .replace("file:", "");

      root = URLDecoder.decode(root, StandardCharsets.UTF_8.toString());
      agentManager.setRootPath(root);

      String deviceConfigFilePath = root + AgentConstants.AGENT_PROPERTIES_FILE_NAME;
      propertiesInputStream = new FileInputStream(deviceConfigFilePath);

      // load a properties file from class path, inside static method
      properties.load(propertiesInputStream);

      iotServerConfigs.setTenantDomain(properties.getProperty(AgentConstants.TENANT_DOMAIN));
      iotServerConfigs.setDeviceOwner(properties.getProperty(AgentConstants.DEVICE_OWNER_PROPERTY));
      iotServerConfigs.setDeviceId(properties.getProperty(AgentConstants.DEVICE_ID_PROPERTY));
      iotServerConfigs.setDeviceName(properties.getProperty(AgentConstants.DEVICE_NAME_PROPERTY));
      iotServerConfigs.setControllerContext(
          properties.getProperty(AgentConstants.DEVICE_CONTROLLER_CONTEXT_PROPERTY));
      iotServerConfigs.setScepContext(
          properties.getProperty(AgentConstants.DEVICE_SCEP_CONTEXT_PROPERTY));
      iotServerConfigs.setHTTPS_ServerEndpoint(
          properties.getProperty(AgentConstants.SERVER_HTTPS_EP_PROPERTY));
      iotServerConfigs.setHTTP_ServerEndpoint(
          properties.getProperty(AgentConstants.SERVER_HTTP_EP_PROPERTY));
      iotServerConfigs.setApimGatewayEndpoint(
          properties.getProperty(AgentConstants.APIM_GATEWAY_EP_PROPERTY));
      iotServerConfigs.setMqttBrokerEndpoint(
          properties.getProperty(AgentConstants.MQTT_BROKER_EP_PROPERTY));
      iotServerConfigs.setXmppServerEndpoint(
          properties.getProperty(AgentConstants.XMPP_SERVER_EP_PROPERTY));
      iotServerConfigs.setXmppServerName(
          properties.getProperty(AgentConstants.XMPP_SERVER_NAME_PROPERTY));
      iotServerConfigs.setAuthMethod(properties.getProperty(AgentConstants.AUTH_METHOD_PROPERTY));
      iotServerConfigs.setAuthToken(properties.getProperty(AgentConstants.AUTH_TOKEN_PROPERTY));
      iotServerConfigs.setRefreshToken(
          properties.getProperty(AgentConstants.REFRESH_TOKEN_PROPERTY));
      iotServerConfigs.setDataPushInterval(
          Integer.parseInt(properties.getProperty(AgentConstants.PUSH_INTERVAL_PROPERTY)));

      log.info(
          AgentConstants.LOG_APPENDER + "Tenant Domain: " + iotServerConfigs.getTenantDomain());
      log.info(AgentConstants.LOG_APPENDER + "Device Owner: " + iotServerConfigs.getDeviceOwner());
      log.info(AgentConstants.LOG_APPENDER + "Device ID: " + iotServerConfigs.getDeviceId());
      log.info(AgentConstants.LOG_APPENDER + "Device Name: " + iotServerConfigs.getDeviceName());
      log.info(
          AgentConstants.LOG_APPENDER
              + "Device Controller Context: "
              + iotServerConfigs.getControllerContext());
      log.info(
          AgentConstants.LOG_APPENDER
              + "IoT Server HTTPS EndPoint: "
              + iotServerConfigs.getHTTPS_ServerEndpoint());
      log.info(
          AgentConstants.LOG_APPENDER
              + "IoT Server HTTP EndPoint: "
              + iotServerConfigs.getHTTP_ServerEndpoint());
      log.info(
          AgentConstants.LOG_APPENDER
              + "API-Manager Gateway EndPoint: "
              + iotServerConfigs.getApimGatewayEndpoint());
      log.info(
          AgentConstants.LOG_APPENDER
              + "MQTT Broker EndPoint: "
              + iotServerConfigs.getMqttBrokerEndpoint());
      log.info(
          AgentConstants.LOG_APPENDER
              + "XMPP Server EndPoint: "
              + iotServerConfigs.getXmppServerEndpoint());
      log.info(
          AgentConstants.LOG_APPENDER
              + "Authentication Method: "
              + iotServerConfigs.getAuthMethod());
      log.info(
          AgentConstants.LOG_APPENDER + "Authentication Token: " + iotServerConfigs.getAuthToken());
      log.info(
          AgentConstants.LOG_APPENDER + "Refresh Token: " + iotServerConfigs.getRefreshToken());
      log.info(
          AgentConstants.LOG_APPENDER
              + "Data Push Interval: "
              + iotServerConfigs.getDataPushInterval());
      log.info(
          AgentConstants.LOG_APPENDER
              + "XMPP Server Name: "
              + iotServerConfigs.getXmppServerName());

    } catch (FileNotFoundException ex) {
      String errorMsg =
          "[" + propertiesFileName + "] file not found at: " + AgentConstants.PROPERTIES_FILE_PATH;
      log.error(AgentConstants.LOG_APPENDER + errorMsg);
      throw new AgentCoreOperationException(errorMsg);

    } catch (IOException ex) {
      String errorMsg =
          "Error occurred whilst trying to fetch ["
              + propertiesFileName
              + "] from: "
              + AgentConstants.PROPERTIES_FILE_PATH;
      log.error(AgentConstants.LOG_APPENDER + errorMsg);
      throw new AgentCoreOperationException(errorMsg);
    } finally {
      if (propertiesInputStream != null) {
        try {
          propertiesInputStream.close();
        } catch (IOException e) {
          log.error(
              AgentConstants.LOG_APPENDER
                  + "Error occurred whilst trying to close InputStream resource used to read the '"
                  + propertiesFileName
                  + "' file");
        }
      }
    }
    return iotServerConfigs;
  }