/*
 *************************************************************************
 * 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) 2010-2017 Openbravo SLU
 * All Rights Reserved. 
 * Contributor(s):  ______________________________________.
 ************************************************************************
 */
package org.openbravo.test.model;

import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.Matchers.empty;
import static org.junit.Assert.assertThat;

import java.util.ArrayList;
import java.util.List;

import org.apache.log4j.Logger;
import org.hibernate.criterion.Restrictions;
import org.junit.Test;
import org.openbravo.dal.service.OBCriteria;
import org.openbravo.dal.service.OBDal;
import org.openbravo.erpCommon.ad_callouts.SimpleCallout;
import org.openbravo.model.ad.domain.ModelImplementation;
import org.openbravo.model.ad.domain.ModelImplementationMapping;
import org.openbravo.test.base.OBBaseTest;

/**
 * Tests for extra unneded mappings for callouts based on SimpleCallout. Since PR16Q4 those do no
 * longer need a url mapping, as they are no longer servlets.
 * 
 * @author huehner
 */
public class SimpleCalloutMappingTest extends OBBaseTest {

  private static final Logger log = Logger.getLogger(SimpleCalloutMappingTest.class);
  private static List<String> extraMappings = new ArrayList<String>();
  private static boolean initialized = false;

  /**
   * Test if all registered classes in Application Dictionary can be loaded. Consistency test to
   * have a clean web.xml
   */
  @Test
  public void simpleCalloutsShouldNotHaveUrlMappings() {
    loadModel();

    logErrors(extraMappings, "Extra unneeded mappings");
    assertThat("Extra unneeded url mappings for SimpleCallouts", extraMappings, is(empty()));
  }

  private void loadModel() {
    if (initialized) {
      return;
    }

    initialized = true;
    extraMappings = new ArrayList<String>();

    setSystemAdministratorContext();

    // "S" - "Servlet"

    // Checking manual callouts extending SimpleCallout
    OBCriteria<ModelImplementation> obc = OBDal.getInstance().createCriteria(
        ModelImplementation.class);
    obc.add(Restrictions.eq(ModelImplementation.PROPERTY_OBJECTTYPE, "S"));
    obc.add(Restrictions.isNotNull(ModelImplementation.PROPERTY_CALLOUT));
    obc.addOrderBy(ModelImplementation.PROPERTY_JAVACLASSNAME, true);

    checkSimpleCallouts("Manual Servlet", obc.list(), extraMappings);

  }

  private void checkSimpleCallouts(String type, List<ModelImplementation> callouts,
      List<String> unneededMappings) {
    for (ModelImplementation mi : callouts) {
      try {
        Class<?> clz = Class.forName(mi.getJavaClassName());
        if (SimpleCallout.class.isAssignableFrom(clz)) {
          // callout implements SimpleCallout -> no html mappings needed
          List<ModelImplementationMapping> mappings = mi.getADModelImplementationMappingList();
          if (!mappings.isEmpty()) {
            unneededMappings.add("SimpleCallout: " + mi.getJavaClassName() + " has "
                + mappings.size() + " URL mappings which are not needed and should be removed.");
          }
        }

      } catch (ClassNotFoundException e) {
        // already covered by ClassLoaderTest
      }
    }
  }

  private void logErrors(final List<String> classes, String msg) {
    if (classes.isEmpty()) {
      return;
    }
    log.error("== " + msg + " ==");
    for (String nf : classes) {
      log.error("  " + nf);
    }
    log.error("Total: " + classes.size());
  }
}
