/*
 *************************************************************************
 * The contents of this file are subject to the Openbravo  Public  License
 * Version  1.1  (the  "License"),  being   the  Mozilla   Public  License
 * Version 1.1  with a permitted attribution clause; you may not  use this
 * file except in compliance with the License. You  may  obtain  a copy of
 * the License at http://www.openbravo.com/legal/license.html 
 * Software distributed under the License  is  distributed  on  an "AS IS"
 * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
 * License for the specific  language  governing  rights  and  limitations
 * under the License. 
 * The Original Code is Openbravo ERP. 
 * The Initial Developer of the Original Code is Openbravo SLU 
 * All portions are Copyright (C) 2019 Openbravo SLU
 * All Rights Reserved. 
 * Contributor(s):  ______________________________________.
 ************************************************************************
 */
package org.openbravo.test.datasource;

import static org.junit.Assert.fail;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;

import org.codehaus.jettison.json.JSONArray;
import org.codehaus.jettison.json.JSONException;
import org.codehaus.jettison.json.JSONObject;
import org.junit.Before;
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class MyOpenbravoActionHandlerConcurrencyTest extends BaseDataSourceTestDal {

  private static final Logger log = LoggerFactory
      .getLogger(MyOpenbravoActionHandlerConcurrencyTest.class);
  private static final String CONTEXT_ROLE = "45C861D70874409D86AE1CC7007AB43A";
  private static final String AMERICAN_ORGANIZATION = "BAE22373FEBE4CCCA24517E23F0C8A48";
  private static final String LANGUAGE_ID = "192";
  private static final String WAREHOUSE_ID = "4D45FE4C515041709047F51D139A21AC";

  @Before
  public void authenticateUser() throws Exception {
    authenticate();
  }

  @Test
  public void testRequest() throws Exception {
    changeProfile(CONTEXT_ROLE, LANGUAGE_ID, AMERICAN_ORGANIZATION, WAREHOUSE_ID);
    int threads = 20;
    ExecutorService executor = Executors.newFixedThreadPool(threads);
    List<Requester> requesters = new ArrayList<>();
    for (int i = 0; i < threads; i++) {
      requesters.add(new Requester());
    }
    log.info("*** Starting execution with {} threads ***", threads);
    long t = System.currentTimeMillis();
    List<Future<String>> results = executor.invokeAll(requesters, 1, TimeUnit.HOURS);
    for (Future<String> result : results) {
      if (result.get() == null) {
        fail("Request failed");
      }
      log.info("Request result: " + result.get());
    }
    log.info("*** Requests with {} threads done in {} ms ***", threads, System.currentTimeMillis()
        - t);
  }

  private class Requester implements Callable<String> {

    @Override
    public String call() throws Exception {
      try {
        String response = doRequest(
            "/org.openbravo.client.kernel?_action=org.openbravo.client.myob.MyOpenbravoActionHandler",
            getRequestInfo(), 200, "POST", "application/json;charset=UTF-8");
        return response;
      } catch (Exception ex) {
        return null;
      }
    }

    private String getRequestInfo() throws JSONException {
      JSONObject dataObject = new JSONObject();
      JSONObject context = new JSONObject();
      context.put("adminMode", false);
      dataObject.put("eventType", "RELOAD_WIDGETS");
      dataObject.put("widgets", new JSONArray());
      dataObject.put("context", context);
      return dataObject.toString();
    }
  }
}