/** @author <a href="mailto:[email protected]">Jean Deruelle</a> */
@RunWith(Arquillian.class)
public class VoxboneAvailablePhoneNumbersEndpointTest {
  private static final Logger logger =
      Logger.getLogger(VoxboneAvailablePhoneNumbersEndpointTest.class.getName());

  private static final String version = org.mobicents.servlet.restcomm.Version.getVersion();

  @ArquillianResource private Deployer deployer;
  @ArquillianResource URL deploymentUrl;
  static boolean accountUpdated = false;

  private String adminUsername = "******";
  private String adminAccountSid = "ACae6e420f425248d6a26948c17a9e2acf";
  private String adminAuthToken = "77f8c12cc7b8f8423e5c38b035249166";
  private String baseURL = "2012-04-24/Accounts/" + adminAccountSid + "/AvailablePhoneNumbers/";

  @Rule
  public WireMockRule wireMockRule =
      new WireMockRule(8090); // No-args constructor defaults to port 8080

  /*
   * https://www.twilio.com/docs/api/rest/available-phone-numbers#local-get-basic-example-1
   * available local phone numbers in the United States in the 510 area code.
   */
  @Test
  public void testSearchUSLocalPhoneNumbersWith501AreaCode() {
    stubFor(
        put(urlEqualTo("/test/configuration/voiceuri"))
            .willReturn(
                aResponse()
                    .withStatus(200)
                    .withHeader("Content-Type", "application/json")
                    .withBody(VoxboneAvailablePhoneNumbersEndpointTestUtils.VoiceURIJSonResponse)));
    stubFor(
        get(urlEqualTo(
                "/test/inventory/didgroup?countryCodeA3=USA&areaCode=501&pageNumber=0&pageSize=50"))
            .willReturn(
                aResponse()
                    .withStatus(200)
                    .withHeader("Content-Type", "application/json")
                    .withBody(VoxboneAvailablePhoneNumbersEndpointTestUtils.body501AreaCode)));
    // Get Account using admin email address and user email address
    Client jerseyClient = Client.create();
    jerseyClient.addFilter(new HTTPBasicAuthFilter(adminUsername, adminAuthToken));

    String provisioningURL = deploymentUrl + baseURL + "US/Local.json";
    WebResource webResource = jerseyClient.resource(provisioningURL);

    ClientResponse clientResponse =
        webResource
            .queryParam("areaCode", "501")
            .accept("application/json")
            .get(ClientResponse.class);
    assertTrue(clientResponse.getStatus() == 200);
    String response = clientResponse.getEntity(String.class);
    System.out.println(response);
    assertTrue(!response.trim().equalsIgnoreCase("[]"));
    JsonParser parser = new JsonParser();
    JsonArray jsonResponse = parser.parse(response).getAsJsonArray();

    System.out.println(jsonResponse);

    assertTrue(jsonResponse.size() == 15);
    System.out.println((jsonResponse.get(0).getAsJsonObject().toString()));
    assertTrue(
        jsonResponse
            .get(0)
            .getAsJsonObject()
            .toString()
            .equalsIgnoreCase(
                VoxboneAvailablePhoneNumbersEndpointTestUtils.firstJSonResult501AreaCode));
  }

  /*
   * Testing https://docs.nexmo.com/index.php/developer-api/number-search Example 1
   */
  @Test
  public void testSearchESPhoneNumbers700Pattern() {
    stubFor(
        put(urlEqualTo("/test/configuration/voiceuri"))
            .willReturn(
                aResponse()
                    .withStatus(200)
                    .withHeader("Content-Type", "application/json")
                    .withBody(VoxboneAvailablePhoneNumbersEndpointTestUtils.VoiceURIJSonResponse)));
    stubFor(
        get(urlEqualTo("/test/inventory/didgroup?countryCodeA3=ESP&pageNumber=0&pageSize=50"))
            .willReturn(
                aResponse()
                    .withStatus(200)
                    .withHeader("Content-Type", "application/json")
                    .withBody(VoxboneAvailablePhoneNumbersEndpointTestUtils.jsonResponseES700)));
    Client jerseyClient = Client.create();
    jerseyClient.addFilter(new HTTPBasicAuthFilter(adminUsername, adminAuthToken));

    String provisioningURL = deploymentUrl + baseURL + "ES/Local.json";
    WebResource webResource = jerseyClient.resource(provisioningURL);

    ClientResponse clientResponse =
        webResource
            .queryParam("Contains", "700")
            .accept("application/json")
            .get(ClientResponse.class);
    assertTrue(clientResponse.getStatus() == 200);
    String response = clientResponse.getEntity(String.class);
    System.out.println(response);
    assertTrue(!response.trim().equalsIgnoreCase("[]"));
    JsonParser parser = new JsonParser();
    JsonArray jsonResponse = parser.parse(response).getAsJsonArray();

    System.out.println(jsonResponse);

    assertTrue(jsonResponse.size() == 48);
    System.out.println((jsonResponse.get(0).getAsJsonObject().toString()));
    assertTrue(
        jsonResponse
            .get(0)
            .getAsJsonObject()
            .toString()
            .equalsIgnoreCase(VoxboneAvailablePhoneNumbersEndpointTestUtils.jsonResultES700));
  }

  /*
   * Testing https://docs.nexmo.com/index.php/developer-api/number-search Example 2
   */
  @Test
  public void testSearchUSPhoneNumbersRangeIndexAndSize() {
    stubFor(
        put(urlEqualTo("/test/configuration/voiceuri"))
            .willReturn(
                aResponse()
                    .withStatus(200)
                    .withHeader("Content-Type", "application/json")
                    .withBody(VoxboneAvailablePhoneNumbersEndpointTestUtils.VoiceURIJSonResponse)));
    stubFor(
        get(urlEqualTo("/test/inventory/didgroup?countryCodeA3=USA&pageNumber=2&pageSize=5"))
            .willReturn(
                aResponse()
                    .withStatus(200)
                    .withHeader("Content-Type", "application/json")
                    .withBody(VoxboneAvailablePhoneNumbersEndpointTestUtils.jsonResponseUSRange)));
    // Get Account using admin email address and user email address
    Client jerseyClient = Client.create();
    jerseyClient.addFilter(new HTTPBasicAuthFilter(adminUsername, adminAuthToken));

    String provisioningURL = deploymentUrl + baseURL + "US/Local.json";
    WebResource webResource = jerseyClient.resource(provisioningURL);

    ClientResponse clientResponse =
        webResource
            .queryParam("RangeSize", "5")
            .queryParam("RangeIndex", "2")
            .accept("application/json")
            .get(ClientResponse.class);
    assertTrue(clientResponse.getStatus() == 200);
    String response = clientResponse.getEntity(String.class);
    System.out.println(response);
    assertTrue(!response.trim().equalsIgnoreCase("[]"));
    JsonParser parser = new JsonParser();
    JsonArray jsonResponse = parser.parse(response).getAsJsonArray();

    System.out.println(jsonResponse);

    assertTrue(jsonResponse.size() == 5);
    System.out.println((jsonResponse.get(0).getAsJsonObject().toString()));
    assertTrue(
        jsonResponse
            .get(0)
            .getAsJsonObject()
            .toString()
            .equalsIgnoreCase(VoxboneAvailablePhoneNumbersEndpointTestUtils.jsonResultUSRange));
  }

  @Deployment(name = "VoxboneAvailablePhoneNumbersEndpointTest", managed = true, testable = false)
  public static WebArchive createWebArchiveNoGw() {
    logger.info("Packaging Test App");
    logger.info("version");
    WebArchive archive = ShrinkWrap.create(WebArchive.class, "restcomm.war");
    final WebArchive restcommArchive =
        ShrinkWrapMaven.resolver()
            .resolve("com.telestax.servlet:restcomm.application:war:" + version)
            .withoutTransitivity()
            .asSingle(WebArchive.class);
    archive = archive.merge(restcommArchive);
    archive.delete("/WEB-INF/sip.xml");
    archive.delete("/WEB-INF/conf/restcomm.xml");
    archive.delete("/WEB-INF/data/hsql/restcomm.script");
    archive.addAsWebInfResource("sip.xml");
    archive.addAsWebInfResource("restcomm_voxbone_test.xml", "conf/restcomm.xml");
    archive.addAsWebInfResource("restcomm.script_dialTest", "data/hsql/restcomm.script");
    logger.info("Packaged Test App");
    return archive;
  }
}
/** @author [email protected] */
@RunWith(Arquillian.class)
public class ApplicationsEndpointTest {

  private static final Logger logger = Logger.getLogger(ApplicationsEndpointTest.class);
  private static final String version = org.mobicents.servlet.restcomm.Version.getVersion();

  @ArquillianResource private Deployer deployer;
  @ArquillianResource URL deploymentUrl;

  private String adminUsername = "******";
  private String adminAccountSid = "ACae6e420f425248d6a26948c17a9e2acf";
  private String adminAuthToken = "77f8c12cc7b8f8423e5c38b035249166";

  @After
  public void after() throws InterruptedException {
    Thread.sleep(1000);
  }

  @Test
  public void testCreateAndGetApplication()
      throws ParseException, IllegalArgumentException, ClientProtocolException, IOException {
    // Define application attributes
    String friendlyName, voiceCallerIdLookup, rcmlUrl, kind;

    // Test create application via POST
    MultivaluedMap<String, String> applicationParams = new MultivaluedMapImpl();
    applicationParams.add("FriendlyName", friendlyName = "APPCreateGet");
    applicationParams.add("VoiceCallerIdLookup", voiceCallerIdLookup = "true");
    applicationParams.add("RcmlUrl", rcmlUrl = "/restcomm/rcmlurl/test");
    applicationParams.add("Kind", kind = "voice");
    JsonObject applicationJson =
        RestcommApplicationsTool.getInstance()
            .createApplication(
                deploymentUrl.toString(),
                adminAccountSid,
                adminUsername,
                adminAuthToken,
                applicationParams);
    Sid applicationSid = new Sid(applicationJson.get("sid").getAsString());

    // Test asserts via GET to a single application
    applicationJson =
        RestcommApplicationsTool.getInstance()
            .getApplication(
                deploymentUrl.toString(),
                adminUsername,
                adminAuthToken,
                adminAccountSid,
                applicationSid.toString());

    SimpleDateFormat df = new SimpleDateFormat("EEE, d MMM yyyy HH:mm:ss Z", Locale.US);
    assertTrue(df.parse(applicationJson.get("date_created").getAsString()) != null);
    assertTrue(df.parse(applicationJson.get("date_updated").getAsString()) != null);
    assertTrue(applicationJson.get("friendly_name").getAsString().equals(friendlyName));
    assertTrue(applicationJson.get("account_sid").getAsString().equals(adminAccountSid));
    assertTrue(applicationJson.get("api_version").getAsString().equals("2012-04-24"));
    assertTrue(
        applicationJson.get("voice_caller_id_lookup").getAsString().equals(voiceCallerIdLookup));
    assertTrue(applicationJson.get("rcml_url").getAsString().equals(rcmlUrl));
    assertTrue(applicationJson.get("kind").getAsString().equals(kind));

    // Test asserts via GET to a application list
    JsonArray applicationsListJson =
        RestcommApplicationsTool.getInstance()
            .getApplications(
                deploymentUrl.toString(), adminUsername, adminAuthToken, adminAccountSid);
    applicationJson = applicationsListJson.get(0).getAsJsonObject();
    assertTrue(df.parse(applicationJson.get("date_created").getAsString()) != null);
    assertTrue(df.parse(applicationJson.get("date_updated").getAsString()) != null);
    assertTrue(applicationJson.get("friendly_name").getAsString().equals(friendlyName));
    assertTrue(applicationJson.get("account_sid").getAsString().equals(adminAccountSid));
    assertTrue(applicationJson.get("api_version").getAsString().equals("2012-04-24"));
    assertTrue(
        applicationJson.get("voice_caller_id_lookup").getAsString().equals(voiceCallerIdLookup));
    assertTrue(applicationJson.get("rcml_url").getAsString().equals(rcmlUrl));
    assertTrue(applicationJson.get("kind").getAsString().equals(kind));
  }

  @Test
  public void testUpdateApplication()
      throws ParseException, IllegalArgumentException, ClientProtocolException, IOException {
    // Create application
    MultivaluedMap<String, String> applicationParams = new MultivaluedMapImpl();
    applicationParams.add("FriendlyName", "APPUpdate");
    applicationParams.add("VoiceCallerIdLookup", "true");
    applicationParams.add("RcmlUrl", "/restcomm/rcmlurl/test");
    applicationParams.add("Kind", "voice");
    JsonObject applicationJson =
        RestcommApplicationsTool.getInstance()
            .createApplication(
                deploymentUrl.toString(),
                adminAccountSid,
                adminUsername,
                adminAuthToken,
                applicationParams);
    Sid applicationSid = new Sid(applicationJson.get("sid").getAsString());

    // Define new values to the application attributes (POST test)
    String friendlyName, voiceCallerIdLookup, rcmlUrl, kind;

    MultivaluedMap<String, String> applicationParamsUpdate = new MultivaluedMapImpl();
    applicationParamsUpdate.add("FriendlyName", friendlyName = "APPUpdate2");
    applicationParamsUpdate.add("VoiceCallerIdLookup", voiceCallerIdLookup = "false");
    applicationParamsUpdate.add("RcmlUrl", rcmlUrl = "/restcomm/rcmlurl/test2");
    applicationParamsUpdate.add("Kind", kind = "voice");

    // Update application via POST
    RestcommApplicationsTool.getInstance()
        .updateApplication(
            deploymentUrl.toString(),
            adminUsername,
            adminAuthToken,
            adminAccountSid,
            applicationSid.toString(),
            applicationParamsUpdate,
            false);

    // Test asserts via GET to a single application
    applicationJson =
        RestcommApplicationsTool.getInstance()
            .getApplication(
                deploymentUrl.toString(),
                adminUsername,
                adminAuthToken,
                adminAccountSid,
                applicationSid.toString());

    SimpleDateFormat df = new SimpleDateFormat("EEE, d MMM yyyy HH:mm:ss Z", Locale.US);
    assertTrue(df.parse(applicationJson.get("date_created").getAsString()) != null);
    assertTrue(df.parse(applicationJson.get("date_updated").getAsString()) != null);
    assertTrue(applicationJson.get("friendly_name").getAsString().equals(friendlyName));
    assertTrue(applicationJson.get("account_sid").getAsString().equals(adminAccountSid));
    assertTrue(applicationJson.get("api_version").getAsString().equals("2012-04-24"));
    assertTrue(
        applicationJson.get("voice_caller_id_lookup").getAsString().equals(voiceCallerIdLookup));
    assertTrue(applicationJson.get("rcml_url").getAsString().equals(rcmlUrl));
    assertTrue(applicationJson.get("kind").getAsString().equals(kind));

    // Define new values to the application attributes (PUT test)
    applicationParamsUpdate = new MultivaluedMapImpl();
    applicationParamsUpdate.add("FriendlyName", friendlyName = "APPUpdate23");
    applicationParamsUpdate.add("VoiceCallerIdLookup", voiceCallerIdLookup = "true");
    applicationParamsUpdate.add("RcmlUrl", rcmlUrl = "/restcomm/rcmlurl/test23");
    applicationParamsUpdate.add("Kind", kind = "voice");

    // Update application via PUT
    RestcommApplicationsTool.getInstance()
        .updateApplication(
            deploymentUrl.toString(),
            adminUsername,
            adminAuthToken,
            adminAccountSid,
            applicationSid.toString(),
            applicationParamsUpdate,
            true);

    // Test asserts via GET to a single application
    applicationJson =
        RestcommApplicationsTool.getInstance()
            .getApplication(
                deploymentUrl.toString(),
                adminUsername,
                adminAuthToken,
                adminAccountSid,
                applicationSid.toString());

    assertTrue(df.parse(applicationJson.get("date_created").getAsString()) != null);
    assertTrue(df.parse(applicationJson.get("date_updated").getAsString()) != null);
    assertTrue(applicationJson.get("friendly_name").getAsString().equals(friendlyName));
    assertTrue(applicationJson.get("account_sid").getAsString().equals(adminAccountSid));
    assertTrue(applicationJson.get("api_version").getAsString().equals("2012-04-24"));
    assertTrue(
        applicationJson.get("voice_caller_id_lookup").getAsString().equals(voiceCallerIdLookup));
    assertTrue(applicationJson.get("rcml_url").getAsString().equals(rcmlUrl));
    assertTrue(applicationJson.get("kind").getAsString().equals(kind));
  }

  @Test
  public void testDeleteApplication()
      throws IllegalArgumentException, ClientProtocolException, IOException {
    // Create application
    MultivaluedMap<String, String> applicationParams = new MultivaluedMapImpl();
    applicationParams.add("FriendlyName", "APPDelete");
    applicationParams.add("VoiceCallerIdLookup", "true");
    applicationParams.add("RcmlUrl", "/restcomm/rcmlurl/test");
    applicationParams.add("Kind", "voice");
    JsonObject applicationJson =
        RestcommApplicationsTool.getInstance()
            .createApplication(
                deploymentUrl.toString(),
                adminAccountSid,
                adminUsername,
                adminAuthToken,
                applicationParams);
    Sid applicationSid = new Sid(applicationJson.get("sid").getAsString());

    // Delete application
    RestcommApplicationsTool.getInstance()
        .deleteApplication(
            deploymentUrl.toString(),
            adminUsername,
            adminAuthToken,
            adminAccountSid,
            applicationSid.toString());

    // Check if it was removed
    applicationJson =
        RestcommApplicationsTool.getInstance()
            .getApplication(
                deploymentUrl.toString(),
                adminUsername,
                adminAuthToken,
                adminAccountSid,
                applicationSid.toString());

    assertTrue(applicationJson == null);
  }

  @Deployment(name = "ApplicationsEndpointTest", managed = true, testable = false)
  public static WebArchive createWebArchiveNoGw() {
    logger.info("Packaging Test App");
    logger.info("version");
    WebArchive archive = ShrinkWrap.create(WebArchive.class, "restcomm.war");
    final WebArchive restcommArchive =
        ShrinkWrapMaven.resolver()
            .resolve("com.telestax.servlet:restcomm.application:war:" + version)
            .withoutTransitivity()
            .asSingle(WebArchive.class);
    archive = archive.merge(restcommArchive);
    archive.delete("/WEB-INF/sip.xml");
    archive.delete("/WEB-INF/conf/restcomm.xml");
    archive.delete("/WEB-INF/data/hsql/restcomm.script");
    archive.addAsWebInfResource("sip.xml");
    archive.addAsWebInfResource("restcomm.xml", "conf/restcomm.xml");
    archive.addAsWebInfResource("restcomm.script", "data/hsql/restcomm.script");
    logger.info("Packaged Test App");
    return archive;
  }
}