/**
 * This file is part of the Meeds project (https://meeds.io/).
 *
 * Copyright (C) 2020 - 2025 Meeds Association contact@meeds.io
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 3 of the License, or (at your option) any later version.
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with this program; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
 */
package org.exoplatform.social.common.service.impl;

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

import org.exoplatform.container.PortalContainer;
import org.exoplatform.social.common.service.ExecutorServiceManager;
import org.exoplatform.social.common.service.LifecycleService;
import org.exoplatform.social.common.service.ProcessContext;
import org.exoplatform.social.common.service.SocialServiceContext;
import org.exoplatform.social.common.service.SocialServiceExecutor;
import org.exoplatform.social.common.service.TraceFactory;
import org.exoplatform.social.common.service.thread.ThreadPoolConfig;
import org.exoplatform.social.common.service.utils.TraceList;

public class SocialServiceContextImpl implements SocialServiceContext {
  
  private static ExecutorServiceManager executorServiceManager = new ExecutorServiceManagerImpl();
  
  private final SocialServiceExecutor serviceExecutor;
  
  private List<LifecycleService> lifecycleServices = new ArrayList<LifecycleService>();
  
  private static SocialServiceContext instance;
  
  private final TraceFactory traceFactory;
  
  private TraceList traceList;
  
  private ProcessType isAsyn = ProcessType.SYNC;
  
  private SocialServiceContextImpl() {
    this.traceFactory = TraceFactory.defaultFactory;
    Object obj = PortalContainer.getInstance().getComponentInstanceOfType(ThreadPoolConfig.class);
    if (obj != null) {
      ThreadPoolConfig config = (ThreadPoolConfig)obj;
      boolean async = config.isAsyncMode();
      this.isAsyn = async ? ProcessType.ASYNC : ProcessType.SYNC;
      
      serviceExecutor = new SocialServiceExecutorImpl(executorServiceManager.newThreadPool("Social", config));
    } else {
      serviceExecutor = new SocialServiceExecutorImpl(executorServiceManager.newDefaultThreadPool("Social"));
    }
    
  }
  
  public static synchronized SocialServiceContext getInstance() {
    if (instance == null) {
      instance = new SocialServiceContextImpl();
    }
    
    return instance;
  }
  
  public static ProcessContext createProcessContext() {
    return new ProcessorContextImpl(getInstance());
  }
  
  @Override
  public List<LifecycleService> getLifecycleServices() {
    return null;
  }
  
  @Override
  public void addLifecycleService(LifecycleService lifecycleService) {
    lifecycleServices.add(lifecycleService);
  }

  @Override
  public SocialServiceExecutor getServiceExecutor() {
    return serviceExecutor;
  }
  
  public ExecutorServiceManager getExecutorServiceManager() {
    return executorServiceManager;
}

  @Override
  public TraceList getTraceList() {
    if (traceList == null) {
      traceList = traceFactory.make();
    }
    return traceList;
  }

  @Override
  public boolean isTraced() {
    return false;
  }
  
  @Override
  public boolean isAsync() {
    return this.isAsyn == ProcessType.ASYNC;
  }
  
}
