/**
 * Copyright (C) 2012 - present by OpenGamma Inc. and the OpenGamma group of companies
 * 
 * Please see distribution for license.
 */
package com.opengamma.integration.tool.portfolio;

import java.util.HashSet;
import java.util.Set;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.google.common.collect.Sets;
import com.opengamma.component.factory.tool.RemoteComponentFactoryToolContextAdapter;
import com.opengamma.component.tool.AbstractComponentTool;
import com.opengamma.financial.tool.ToolContext;
import com.opengamma.id.ObjectId;
import com.opengamma.id.UniqueId;
import com.opengamma.master.portfolio.ManageablePortfolioNode;
import com.opengamma.master.portfolio.PortfolioDocument;
import com.opengamma.master.portfolio.PortfolioMaster;
import com.opengamma.master.portfolio.PortfolioSearchRequest;
import com.opengamma.master.portfolio.PortfolioSearchResult;
import com.opengamma.master.position.PositionDocument;
import com.opengamma.master.position.PositionMaster;
import com.opengamma.master.position.PositionSearchRequest;
import com.opengamma.master.position.PositionSearchResult;

/**
 * Deletes positions that are not currently in a portfolio
 */
public class OrphanedPositionDeleteTool extends AbstractComponentTool {
  
  private static final Logger s_logger = LoggerFactory.getLogger(OrphanedPositionDeleteTool.class);
  /**
   * Main method to run the tool.
   */
  public static void main(String[] args) { // CSIGNORE
    new OrphanedPositionDeleteTool().initAndRun(args);
    System.exit(0);
  }

  @Override
  protected void doRun() throws Exception {
    ToolContext toolContext = new RemoteComponentFactoryToolContextAdapter(getRemoteComponentFactory());
    PortfolioMaster portfolioMaster = toolContext.getPortfolioMaster();
    
    PortfolioSearchRequest request = new PortfolioSearchRequest();  
    Set<ObjectId> validPositions = Sets.newHashSet();
    
    PortfolioSearchResult portfolioSearchResult = portfolioMaster.search(request);
    
    for (PortfolioDocument portfolioDocument : portfolioSearchResult.getDocuments()) {
      validPositions.addAll(PositionAccumulator.getAccumulatedPositions(portfolioDocument.getPortfolio().getRootNode()));
    }
        
    PositionMaster positionMaster = toolContext.getPositionMaster();
    
    s_logger.info("removing orphaned positions");
    
    PositionSearchResult positionSearchResult = positionMaster.search(new PositionSearchRequest());
    for (PositionDocument positionDocument : positionSearchResult.getDocuments()) {
      UniqueId positionId = positionDocument.getPosition().getUniqueId();
      if (!validPositions.contains(positionId.getObjectId())) {
        positionMaster.remove(positionId);
        s_logger.info("removed position {}", positionId);
      }
    }
  }
  
  private static final class PositionAccumulator {
    
    /**
     * The set of positions.
     */
    private final Set<ObjectId> _positions = new HashSet<ObjectId>();
    
    private PositionAccumulator(final ManageablePortfolioNode node) {
      _positions.addAll(node.getPositionIds());
      for (ManageablePortfolioNode childNode : node.getChildNodes()) {
        _positions.addAll(PositionAccumulator.getAccumulatedPositions(childNode));
      }
    }

    public static Set<ObjectId> getAccumulatedPositions(final ManageablePortfolioNode node) {
      return new PositionAccumulator(node).getPositions();
    }

    /**
     * Gets the positions.
     * @return the positions
     */
    public Set<ObjectId> getPositions() {
      return _positions;
    } 
  }
    
}

@@ -187,57 +187,8 @@
 o;%0A%0A
-import java.util.HashSet;%0Aimport java.util.Set;%0A%0A
 impo
@@ -245,47 +245,8 @@
 y;%0A%0A
-import com.google.common.collect.Sets;%0A
 impo
@@ -439,616 +439,30 @@
 xt;%0A
-import com.opengamma.id.ObjectId;%0Aimport com.opengamma.id.UniqueId;%0Aimport com.opengamma.master.portfolio.ManageablePortfolioNode;%0Aimport com.opengamma.master.portfolio.PortfolioDocument;%0Aimport com.opengamma.master.portfolio.PortfolioMaster;%0Aimport com.opengamma.master.portfolio.PortfolioSearchRequest;%0Aimport com.opengamma.master.portfolio.PortfolioSearchResult;%0Aimport com.opengamma.master.position.PositionDocument;%0Aimport com.opengamma.master.position.PositionMaster;%0Aimport com.opengamma.master.position.PositionSearchRequest;%0Aimport com.opengamma.master.position.PositionSearchResult;%0A%0A/**%0A * D
+%0A/**%0A * Tool to d
 elete
-s
  pos
@@ -1035,1870 +1035,248 @@
     
-PortfolioMaster portfolioMaster = toolContext.getPortfolioMaster();%0A    %0A    PortfolioSearchRequest request = new PortfolioSearchRequest();  %0A    Set%3CObjectId%3E validPositions = Sets.newHashSet();%0A    %0A    PortfolioSearchResult portfolioSearchResult = portfolioMaster.search(request);%0A    %0A    for (PortfolioDocument portfolioDocument : portfolioSearchResult.getDocuments()) %7B%0A      validPositions.addAll(PositionAccumulator.getAccumulatedPositions(portfolioDocument.getPortfolio().getRootNode()));%0A    %7D%0A        %0A    PositionMaster positionMaster = toolContext.getPositionMaster();%0A    %0A    s_logger.info(%22removing orphaned positions%22);%0A    %0A    PositionSearchResult positionSearchResult = positionMaster.search(new PositionSearchRequest());%0A    for (PositionDocument positionDocument : positionSearchResult.getDocuments()) %7B%0A      UniqueId positionId = positionDocument.getPosition().getUniqueId();%0A      if (!validPositions.contains(positionId.getObjectId())) %7B%0A        positionMaster.remove(positionId);%0A        s_logger.info(%22removed position %7B%7D%22, positionId);%0A      %7D%0A    %7D%0A  %7D%0A  %0A  private static final class PositionAccumulator %7B%0A    %0A    /**%0A     * The set of positions.%0A     */%0A    private final Set%3CObjectId%3E _positions = new HashSet%3CObjectId%3E();%0A    %0A    private PositionAccumulator(final ManageablePortfolioNode node) %7B%0A      _positions.addAll(node.getPositionIds()
+OrphanedPositionRemover orphanedPositionRemover = new OrphanedPositionRemover(toolContext.getPortfolioMaster(), toolContext.getPositionMaster());%0A    s_logger.info(%22running orphanedPositionRemover%22
 );%0A    
-  
-f
 or
- (ManageablePortfolioNode childNode : node.getChildNodes()) %7B%0A        _positions.addAll(PositionAccumulator.getAccumulatedPositions(childNode));%0A      %7D%0A    %7D%0A%0A    public static Set%3CObjectId%3E getAccumulatedPositions(final ManageablePortfolioNode node) %7B%0A      return new PositionAccumulator(node).getPositions();%0A    %7D%0A%0A    /**%0A     * Gets the positions.%0A     * @return the positions%0A     */%0A    public Set%3CObjectId%3E getPositions() %7B%0A      return _positions;%0A    %7D 
+phanedPositionRemover.run();
 %0A  %7D%0A  
-  
 %0A%7D%0A

refactor OrphanedPositionDeleteTool to use OrphanedPositionRemover