/*
 * Copyright (c) 2015, StrategyQuant - All rights reserved.
 *
 * Code in this file was made in a good faith that it is correct and does what it should. 
 * If you found a bug in this code OR you have an improvement suggestion OR you want to include 
 * your own code snippet into our standard library please contact us at:
 * http://tasks.strategyquant.com/projects/snippets/
 *
 * This code can be used only within StrategyQuant products. 
 * Every owner of valid (free, trial or commercial) license of any StrategyQuant product 
 * is allowed to freely use, copy, modify or make derivative work of this code without limitations,
 * to be used in all StrategyQuant products and share his/her modifications or derivative work 
 * with the StrategyQuant community.
 *  
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, 
 * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR 
 * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES 
 * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 *  
 */
package com.strategyquant.extend.DatabankActions;

import java.util.ArrayList;

import javax.swing.JOptionPane;

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

import com.strategyquant.futurelib.backtester.SymbolsTable;
import com.strategyquant.lib.app.MainApp;
import com.strategyquant.lib.computers.SQPortfolioComputer;
import com.strategyquant.lib.databank.Databank;
import com.strategyquant.lib.databank.DatabankAction;
import com.strategyquant.lib.databank.DatabanksRegistry;
import com.strategyquant.lib.language.L;
import com.strategyquant.lib.plugins.SQGlobalEventMsg;
import com.strategyquant.lib.plugins.SQGlobalEvents;
import com.strategyquant.lib.results.SQOrderList;
import com.strategyquant.lib.results.SQResult;
import com.strategyquant.lib.results.SQResultsGroup;
import com.strategyquant.lib.settings.SQConst;
import com.strategyquant.lib.settings.SQCoreConst;

public class PortfolioSplit extends DatabankAction {
	public static final Logger Log = LoggerFactory.getLogger("PortfolioSplit");
	public SQPortfolioComputer portfolioComputer = new SQPortfolioComputer();

	public PortfolioSplit() {
		setName("Portfolio:"+L.t("Split to single strategies"));
	}
	
	@Override
	public void execute(Databank databank) {
		try {
			for(SQResultsGroup rg : databank.getSelectedResults()) {
				splitPortfolio(rg, "PortfolioStrategy");
			}

			SQGlobalEvents.getInstance().callChangeEvent(SQGlobalEventMsg.EAA_SELECT_DATABANK, SQCoreConst.EAA_DATABANK_SIMPLE_STR);
			
		} catch(Exception e) {
			Log.error("Exc.", e);
			
        	JOptionPane.showMessageDialog(MainApp.getFrame(),
        			L.t("An error has occurred while splitting the portfolio to single strategies.")+"\n"+
        			e.getMessage(),
        			L.t("Portfolio Split error"),
        		    JOptionPane.ERROR_MESSAGE);
        	
        	return;		
		}	
	}
	
	private void splitPortfolio(SQResultsGroup portfolio, String name) throws Exception {
		ArrayList<String> resultKeys = portfolio.getResultKeysList();
		
        if(resultKeys.size() == 1) {
			DatabanksRegistry.get(SQCoreConst.EAA_DATABANK_SIMPLE_STR).add(portfolio);
        	return;
        }

        SymbolsTable symbolsTable = portfolio.getSymbolsTable().clone();
        SQOrderList balanceOrders = portfolio.getBalanceOrders();
        
        if(balanceOrders != null) {
        	balanceOrders = balanceOrders.clone();
        }
        
        for(String resultKey : resultKeys) {
        	
        	if(resultKey.equals(SQConst.SYMBOL_PORTFOLIO)) continue;
        	
            SQOrderList orders = portfolio.getOrdersForResultKey(resultKey);
            
            SQResult result = new SQResult(portfolio.getResult(resultKey).getSettings().clone());

            result.setOrders(orders.clone());
        	
            
            SQResultsGroup singleStrategy = new SQResultsGroup();
            singleStrategy.setSymbolsTable(symbolsTable);
            singleStrategy.addResult(resultKey, result);
            singleStrategy.setBalanceOrders(balanceOrders);

            singleStrategy.set("StrategyName", name+"_"+resultKey);
            singleStrategy.computeResultsStats();
            
            DatabanksRegistry.get(SQCoreConst.EAA_DATABANK_SIMPLE_STR).add(singleStrategy);
        }	
    }

	public String[] getAllowedDatabanks() {
		return new String[]{"*", SQCoreConst.EAA_DATABANK_SIMPLE_STR+','+SQCoreConst.MM_SIM_DATABANK};
	}
	
	@Override
	public String getProduct() {
		return SQCoreConst.PRODUCT_EAA;
	}
	
	@Override
	public int getPreferredPosition() {
		return 6;
	}
}