/*******************************************************************************
 * Copyright (c) 2010-2015 BSI Business Systems Integration AG.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *     BSI Business Systems Integration AG - initial API and implementation
 ******************************************************************************/
package org.eclipse.scout.rt.platform.internal;

import java.awt.GraphicsEnvironment;
import java.util.ArrayList;
import java.util.EnumSet;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.concurrent.atomic.AtomicReference;
import java.util.concurrent.locks.ReentrantReadWriteLock;

import org.eclipse.scout.rt.platform.BEANS;
import org.eclipse.scout.rt.platform.IBean;
import org.eclipse.scout.rt.platform.IBeanDecorationFactory;
import org.eclipse.scout.rt.platform.IBeanManager;
import org.eclipse.scout.rt.platform.IPlatform;
import org.eclipse.scout.rt.platform.IPlatformListener;
import org.eclipse.scout.rt.platform.Platform;
import org.eclipse.scout.rt.platform.PlatformEvent;
import org.eclipse.scout.rt.platform.PlatformStateLatch;
import org.eclipse.scout.rt.platform.SimpleBeanDecorationFactory;
import org.eclipse.scout.rt.platform.config.CONFIG;
import org.eclipse.scout.rt.platform.config.ConfigUtility;
import org.eclipse.scout.rt.platform.config.IConfigProperty;
import org.eclipse.scout.rt.platform.config.PlatformConfigProperties.PlatformDevModeProperty;
import org.eclipse.scout.rt.platform.exception.PlatformException;
import org.eclipse.scout.rt.platform.inventory.ClassInventory;
import org.eclipse.scout.rt.platform.service.IService;
import org.eclipse.scout.rt.platform.util.BeanUtility;
import org.eclipse.scout.rt.platform.util.TypeCastUtility;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * @since 5.1
 */
public class PlatformImplementor implements IPlatform {

  private static final Logger LOG = LoggerFactory.getLogger(PlatformImplementor.class);

  private static final String SCOUT_HEADLESS_PROPERTY = "scout.headless";
  private static final String AWT_HEADLESS_PROPERTY = "java.awt.headless";

  private final ReentrantReadWriteLock m_platformLock = new ReentrantReadWriteLock(true);
  private final Object m_platformStartedLock = new Object();
  private final AtomicReference<State> m_state; // may be read at any time by any thread
  private BeanManagerImplementor m_beanContext;

  public PlatformImplementor() {
    m_state = new AtomicReference<>(State.PlatformStopped);
  }

  @Override
  public State getState() {
    return m_state.get();
  }

  @Override
  public IBeanManager getBeanManager() {
    // use lock to ensure the caller waits until the platform has been started completely
    m_platformLock.readLock().lock();
    try {
      if (getState() == State.PlatformInvalid) {
        throw new PlatformException("The platform is in an invalid state.");
      }
      return m_beanContext;
    }
    finally {
      m_platformLock.readLock().unlock();
    }
  }

  @Override
  public void awaitPlatformStarted() {
    if (isPlatformStarted()) {
      return;
    }
    synchronized (m_platformStartedLock) {
      while (!isPlatformStarted()) {
        try {
          m_platformStartedLock.wait();
        }
        catch (InterruptedException e) {
          // nop
        }
      }
    }
  }

  protected boolean isPlatformStarted() {
    final State state = getState();
    if (state == null || state == State.PlatformInvalid) {
      throw new PlatformException("The platform is in an invalid state.");
    }
    if (state == State.PlatformStopping) {
      throw new PlatformException("The platform is stopping.");
    }
    return state == State.PlatformStarted;
  }

  protected void notifyPlatformStarted() {
    synchronized (m_platformStartedLock) {
      m_platformStartedLock.notifyAll();
    }
  }

  @Override
  public void start() {
    start(null);
  }

  @Override
  public void start(PlatformStateLatch stateLatch) {
    try {
      m_platformLock.writeLock().lock();
      try {
        if (stateLatch != null) {
          stateLatch.release();
        }
        if (m_state.get() != State.PlatformStopped) {
          throw new PlatformException("Platform is not stopped [m_state=" + m_state.get() + "]");
        }

        try {
          validateHeadless();
          m_beanContext = createBeanManager();
          //now all IPlatformListener are registered and can receive platform events
          changeState(State.BeanManagerPrepared, true);

          //validateBeanManager();
          validateConfiguration();
          initBeanDecorationFactory();

          changeState(State.BeanManagerValid, true);
          startCreateImmediatelyBeans();
        }
        catch (RuntimeException | Error e) {
          LOG.error("Error during platform startup", e);
          changeState(State.PlatformInvalid, true);
          throw e;
        }
      }
      finally {
        //since we are using a reentrant lock, platform beans can be accessed within platform listeners
        //lock has to be released after the State.BeanManagerValid change to make sure everything is initialized correctly, before beans can be accessed.
        m_platformLock.writeLock().unlock();
      }
      changeState(State.PlatformStarted, true);
    }
    finally {
      notifyPlatformStarted();
    }
  }

  protected void validateHeadless() {
    final boolean scoutHeadless = ConfigUtility.getPropertyBoolean(SCOUT_HEADLESS_PROPERTY, true);
    String awtHeadlessStr = System.getProperty(AWT_HEADLESS_PROPERTY);
    final boolean awtHeadless = TypeCastUtility.castValue(awtHeadlessStr, boolean.class);
    String autoSetMsg = "";
    if (scoutHeadless && !awtHeadless) {
      System.setProperty(AWT_HEADLESS_PROPERTY, "true");
      autoSetMsg = " (automatically set by Scout)";
      awtHeadlessStr = "true";
    }
    boolean graphicsEnvironmentHeadless = GraphicsEnvironment.isHeadless();
    LOG.info("Headless mode: {}={}, {}={}{}, GraphicsEnvironment.isHeadless()={}", SCOUT_HEADLESS_PROPERTY, scoutHeadless,
        AWT_HEADLESS_PROPERTY, awtHeadlessStr, autoSetMsg, graphicsEnvironmentHeadless);

    if (scoutHeadless && !graphicsEnvironmentHeadless) {
      LOG.warn("{} is 'true', but GraphicsEnvironment.isHeadless() reports 'false'. AWT seems to have been already initialized. "
          + "Please try setting the system property {}=true manually when starting the VM. You can turn off this message by setting {}=false",
          SCOUT_HEADLESS_PROPERTY, AWT_HEADLESS_PROPERTY, SCOUT_HEADLESS_PROPERTY);
    }
  }

  protected void validateConfiguration() {
    if (!ConfigUtility.isInitialized()) {
      LOG.info("No {} found. Running with empty configuration.", ConfigUtility.CONFIG_FILE_NAME);
    }

    final List<String> invalidProperties = new ArrayList<>();
    for (IConfigProperty prop : BEANS.all(IConfigProperty.class)) {
      try {
        prop.getValue();
      }
      catch (Exception ex) {
        invalidProperties.add(prop.getKey());
        LOG.error("Failed reading config property '{}'", prop.getKey(), ex);
      }
    }
    if (!invalidProperties.isEmpty()) {
      throw new PlatformException("Cannot start platform due to {} invalid config properties: {}", invalidProperties.size(), invalidProperties);
    }
  }

  protected BeanManagerImplementor createBeanManager() {
    BeanManagerImplementor context = new BeanManagerImplementor();
    Set<Class> allBeans = new BeanFilter().collect(ClassInventory.get());
    for (Class<?> bean : allBeans) {
      context.registerClass(bean);
    }
    return context;
  }

  protected void initBeanDecorationFactory() {
    if (m_beanContext.getBeanDecorationFactory() != null) {
      return;
    }
    IBean<IBeanDecorationFactory> bean = m_beanContext.optBean(IBeanDecorationFactory.class);
    if (bean != null) {
      m_beanContext.setBeanDecorationFactory(bean.getInstance());
      return;
    }
    LOG.warn("Using {}. Please verify that this application really has no client or server side {}", SimpleBeanDecorationFactory.class.getName(), IBeanDecorationFactory.class.getSimpleName());
    m_beanContext.setBeanDecorationFactory(new SimpleBeanDecorationFactory());
  }

  protected void validateBeanManager() {
    try {
      //collect all service interfaces
      HashSet<Class> serviceInterfaces = new HashSet<>();
      for (IBean bean : getBeanManager().getRegisteredBeans(IService.class)) {
        for (Class<?> i : BeanUtility.getInterfacesHierarchy(bean.getBeanClazz(), Object.class)) {
          if (IService.class.isAssignableFrom(i)) {
            serviceInterfaces.add(i);
          }
        }
      }
      for (Class s : serviceInterfaces) {
        if (s.equals(IService.class)) {
          continue;
        }
        try {
          @SuppressWarnings("unchecked")
          List<IBean<Object>> list = getBeanManager().getBeans(s);
          if (list.size() <= 1) {
            continue;
          }
          System.out.println("-------- " + s.getName() + " --------");
          for (IBean<?> bean : list) {
            System.out.println(" @Order(" + BeanHierarchy.orderOf(bean) + ") " + bean.getBeanClazz());
          }
        }
        catch (Exception e) {
          e.printStackTrace();
        }
      }
    }
    catch (Exception e) {
      //nop
    }
  }

  protected void startCreateImmediatelyBeans() {
    ((BeanManagerImplementor) m_beanContext).startCreateImmediatelyBeans();
  }

  @Override
  public void stop() {
    changeState(State.PlatformStopping, true);

    m_platformLock.writeLock().lock();
    try {
      if (Platform.get() == this) {
        Platform.set(null);
      }
      changeState(State.PlatformStopped, false);
      destroyBeanManager();
    }
    finally {
      m_platformLock.writeLock().unlock();
    }
  }

  protected void destroyBeanManager() {
    m_beanContext = null;
  }

  protected void changeState(State newState, boolean throwOnIllegalStateChange) {
    if (newState == null) {
      throw new IllegalArgumentException("new state cannot be null.");
    }
    if (m_state.get() == newState) {
      return;
    }

    EnumSet<State> possibleExpectedCurrentStates = getPreviousStates(newState);
    if (possibleExpectedCurrentStates == null || possibleExpectedCurrentStates.size() == 0) {
      throw new IllegalStateException("Unknown state transition: '" + newState + "' has no preceeding state defined.");
    }

    boolean changed = false;
    for (State expectedCurrentState : possibleExpectedCurrentStates) {
      changed = m_state.compareAndSet(expectedCurrentState, newState);
      if (changed) {
        break;
      }
    }
    if (!changed && throwOnIllegalStateChange) {
      throw new PlatformException(
          "Invalid state change. Current state (" + m_state.get() + ") cannot be changed to " + newState + ". A state change to " + newState + " is only allowed in these states " + possibleExpectedCurrentStates);
    }
    fireStateEvent(newState);
  }

  protected static EnumSet<State> getPreviousStates(State reference) {
    switch (reference) {
      case BeanManagerPrepared:
        return EnumSet.of(State.PlatformStopped);
      case BeanManagerValid:
        return EnumSet.of(State.BeanManagerPrepared);
      case PlatformStarted:
        return EnumSet.of(State.BeanManagerValid);
      case PlatformStopping:
        return EnumSet.of(State.PlatformStarted);
      case PlatformStopped:
        return EnumSet.of(State.PlatformStopping);
      case PlatformInvalid:
        return EnumSet.of(State.BeanManagerPrepared, State.BeanManagerValid, State.PlatformStarted, State.PlatformStopping, State.PlatformStopped);
    }
    return EnumSet.noneOf(State.class);
  }

  protected void fireStateEvent(State newState) {
    PlatformEvent event = new PlatformEvent(this, newState);
    try {
      for (IBean<IPlatformListener> bean : m_beanContext.getBeans(IPlatformListener.class)) {
        IPlatformListener listener = bean.getInstance();
        listener.stateChanged(event);
      }
    }
    catch (RuntimeException | Error e) {
      LOG.error("Error during event listener notification.", e);
      changeState(State.PlatformInvalid, true);
      throw e;
    }
  }

  @Override
  public boolean inDevelopmentMode() {
    return CONFIG.getPropertyValue(PlatformDevModeProperty.class); // cannot be null
  }
}
