/**
 * Copyright (C) 2011 - present by OpenGamma Inc. and the OpenGamma group of companies
 *
 * Please see distribution for license.
 */
package com.opengamma.financial.analytics.conversion;

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

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.threeten.bp.ZonedDateTime;

import com.opengamma.OpenGammaRuntimeException;
import com.opengamma.analytics.financial.instrument.InstrumentDefinition;
import com.opengamma.analytics.financial.instrument.bond.BondFixedSecurityDefinition;
import com.opengamma.analytics.financial.instrument.future.BondFutureDefinition;
import com.opengamma.core.security.SecuritySource;
import com.opengamma.financial.security.FinancialSecurityVisitorAdapter;
import com.opengamma.financial.security.bond.BondSecurity;
import com.opengamma.financial.security.future.BondFutureDeliverable;
import com.opengamma.financial.security.future.BondFutureSecurity;
import com.opengamma.util.ArgumentChecker;

/**
 * Converts bond future securities into the form that is used by the analytics library
 */
public class BondFutureSecurityConverter extends FinancialSecurityVisitorAdapter<InstrumentDefinition<?>> {
  /** The security source */
  private final SecuritySource _securitySource;
  /** Converter for the bonds in the deliverable basket */
  private final BondSecurityConverter _bondConverter;

  private static final Logger s_logger = LoggerFactory.getLogger(BondFutureSecurityConverter.class);
  /**
   * @param securitySource The security source, not null
   * @param bondConverter The bond converter, not null
   */
  public BondFutureSecurityConverter(final SecuritySource securitySource, final BondSecurityConverter bondConverter) {
    ArgumentChecker.notNull(securitySource, "security source");
    ArgumentChecker.notNull(bondConverter, "bond converter");
    _securitySource = securitySource;
    _bondConverter = bondConverter;
  }

  @Override
  public BondFutureDefinition visitBondFutureSecurity(final BondFutureSecurity bondFuture) {
    ArgumentChecker.notNull(bondFuture, "security");
    final ZonedDateTime tradingLastDate = bondFuture.getExpiry().getExpiry();
    final ZonedDateTime noticeFirstDate = bondFuture.getFirstDeliveryDate();
    final ZonedDateTime noticeLastDate = bondFuture.getLastDeliveryDate();
    final double notional = bondFuture.getUnitAmount();
    final List<BondFutureDeliverable> basket = bondFuture.getBasket();
    final int n = basket.size();
    final ArrayList<BondFixedSecurityDefinition> deliverablesList = new ArrayList<>();
    final ArrayList<Double> conversionFactorList = new ArrayList<>();
    

    for (int i = 0; i < n; i++) {
      final BondFutureDeliverable deliverable = basket.get(i);
      final BondSecurity bondSecurity = (BondSecurity) _securitySource.getSingle(deliverable.getIdentifiers());
      if (bondSecurity == null) {
        s_logger.debug("Unable to create underlying bond with identifiers " + deliverable.getIdentifiers() + " in bond future deliverable basket");
      } else {
        deliverablesList.add((BondFixedSecurityDefinition) bondSecurity.accept(_bondConverter));
        conversionFactorList.add(deliverable.getConversionFactor());
      }
    }
    final int m = deliverablesList.size();
    if (m == 0) {
      throw new OpenGammaRuntimeException("Unable to satisfy a single identifier in the bond future deliverable basket for " + bondFuture.toString());
    }
    final BondFixedSecurityDefinition[] deliverables = new BondFixedSecurityDefinition[m];
    final double[] conversionFactor = new double[m];
    for (int j = 0; j < m; j++) {
      deliverables[j] = deliverablesList.get(j);
      conversionFactor[j] = conversionFactorList.get(j);
    }
    
    return new BondFutureDefinition(tradingLastDate, noticeFirstDate, noticeLastDate, notional, deliverables, conversionFactor);
  }
}

@@ -207,99 +207,14 @@
 til.
-Array
 List;%0A
-import java.util.List;%0A%0Aimport org.slf4j.Logger;%0Aimport org.slf4j.LoggerFactory;
 %0Aimp
@@ -1300,109 +1300,8 @@
 r;%0A%0A
-  private static final Logger s_logger = LoggerFactory.getLogger(BondFutureSecurityConverter.class);%0A
   /*
@@ -1744,16 +1744,121 @@
 r;%0A  %7D%0A%0A
+  //FIXME CASE - BondFutureDefinition needs a reference price. Without a trade, where will it come from?%0A
   @Overr
@@ -2407,26 +2407,16 @@
   final 
-ArrayList%3C
 BondFixe
@@ -2434,17 +2434,18 @@
 finition
-%3E
+%5B%5D
  deliver
@@ -2453,32 +2453,45 @@
 bles
-List
  = new 
-ArrayList%3C%3E()
+BondFixedSecurityDefinition%5Bn%5D
 ;%0A  
@@ -2502,25 +2502,16 @@
 nal 
-ArrayList%3CD
+d
 ouble
-%3E
+%5B%5D
  con
@@ -2527,39 +2527,25 @@
 ctor
-List
  = new 
-ArrayList%3C%3E();%0A    %0A
+double%5Bn%5D;
 %0A   
@@ -2796,54 +2796,60 @@
     
-s_logger.debug(%22Unable to create underlying bo
+throw new OpenGammaRuntimeException(%22No security fou
 nd w
@@ -2949,18 +2949,9 @@
    %7D
- else %7B%0A  
+%0A
     
@@ -2964,25 +2964,22 @@
 verables
-List.add(
+%5Bi%5D = 
 (BondFix
@@ -3035,21 +3035,18 @@
 nverter)
-)
 ;%0A
-  
       co
@@ -3063,566 +3063,46 @@
 ctor
-List.add(deliverable.getConversionFactor());%0A      %7D%0A    %7D%0A    final int m = deliverablesList.size();%0A    if (m == 0) %7B%0A      throw new OpenGammaRuntimeException(%22Unable to satisfy a single identifier in the bond future deliverable basket for %22 + bondFuture.toString());%0A    %7D%0A    final BondFixedSecurityDefinition%5B%5D deliverables = new BondFixedSecurityDefinition%5Bm%5D;%0A    final double%5B%5D conversionFactor = new double%5Bm%5D;%0A    for (int j = 0; j %3C m; j++) %7B%0A      deliverables%5Bj%5D = deliverablesList.get(j);%0A      conversionFactor%5Bj%5D = conversionFactorList.get(j
+%5Bi%5D = deliverable.getConversionFactor(
 );%0A 
@@ -3110,13 +3110,8 @@
   %7D%0A
-    %0A
     

Revert "PLAT-5204 Relax restrictions on deliberable bond basket in BondFutureSecurityConverter"