#
# Copyright (c) 2009-2022 CERN. All rights nots expressly granted are
# reserved.
#
# This file is part of iLCDirac
# (see ilcdirac.cern.ch, contact: ilcdirac-support@cern.ch).
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# In applying this licence, CERN does not waive the privileges and
# immunities granted to it by virtue of its status as an
# Intergovernmental Organization or submit itself to any jurisdiction.
#
# 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 General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
"""Test the dirac-fcc-make-productions script."""

from __future__ import absolute_import
import os
import importlib
import six.moves.configparser
from collections import defaultdict

import pytest
from mock import MagicMock as Mock, patch

from DIRAC import S_OK, S_ERROR

from ILCDIRAC.ILCTransformationSystem.Utilities.Utilities import Task
from DIRAC.ConfigurationSystem.Client.Helpers.Operations import Operations

from parameterized import parameterized

# pylint: disable=protected-access, invalid-name, missing-docstring, redefined-outer-name
THE_SCRIPT = "ILCDIRAC.ILCTransformationSystem.scripts.dirac_fcc_make_productions"
theScript = importlib.import_module(THE_SCRIPT)
SCP = "ILCDIRAC.ILCTransformationSystem.scripts.dirac_fcc_make_productions.six.moves.configparser.SafeConfigParser"
__RCSID__ = "$Id$"

CONFIG_DICT = {}

def test_environ():
  """Ensure we are not running optimized python.

  Some assertion in the pytest code are otherwise ignored.
  """
  assert "PYTHONOPTIMIZE" not in os.environ


def configDict():
  """Return dictionary for dirac configuration system."""
  return {'prodGroup': "myProdGroup",
          'detectorModel': 'myDetectorModel',
          'softwareVersion': 'mySoftwareVersion',
          'configVersion': 'key4hep-devel-2',
          'configPackage': 'fccConfig',
          'machine': 'ee',
          'generatorApplication': 'KKMC',
          'generatorSteeringFile': 'somesteeringfile',
          'campaign': 'winter2023',
          'datatype': 'lhe',
          'processes': 'qqbar, WW_incl',
          'energies': '100, 200',
          'processingAfterGen': 'delphesapp',
          'eventsPerJobs': '1000, 2000',
          'productionloglevel': 'DEBUGLEVEL3',
          'outputSE': 'CERN-DST-EOS',
          'finalOutputSE': 'CERN-SRM',
          'additionalName': 'waitForIt',
          'prodIDs': '123, 456',
          'eventsInSplitFiles': '5000, 6000',
          'ProdTypes': 'Gen',
          'MoveTypes': '',
          'MoveStatus': 'Active',
          'MoveGroupSize': '11',
          'overlayEvents': '',
          'overlayEventType': '',
          'cliReco': '--Config.Tracking=Tracked',
          'numberOfTasks': '1, 2',
          'ignoreMetadata': '',
          'taskNames': 'taskA, taskB',
          }


@pytest.fixture
def opsMock():
  """Return fixture for Operations."""
  def mockOpsConfig(*args, **kwargs):  # pylint: disable=unused-argument
    """Mock the operations getValue calls."""
    opsDict = {'DefaultDetectorModel': 'detModel',
               'DefaultConfigVersion': 'Config',
               'DefaultConfigPackage': 'Click',
               'DefaultSoftwareVersion': 'Software',
               'FailOverSE': 'FAIL=SRM',
               'DefaultDelphesAppVersion': '1.9.5',
               'BasePath': '',
              }
    for opName, value in opsDict.items():
      if args[0].endswith(opName):
        return value
    assert args[0] == opsDict
    return None 
  theOps = Mock(name='OpsMock')
  theOps.getValue = Mock(side_effect=mockOpsConfig)
  return theOps


@pytest.fixture
def theChain(opsMock):
  """Return production chain fixture."""
  params = Mock()
  params.additionalName = ''
  params.dryRun = True
  with patch("ILCDIRAC.ILCTransformationSystem.scripts.dirac_fcc_make_productions.FCCDetProdChain.loadParameters",
             new=Mock()), \
       patch("DIRAC.ConfigurationSystem.Client.Helpers.Operations",
             new=Mock(return_value=opsMock)):
    chain = theScript.FCCDetProdChain(params)

  return chain


@pytest.fixture
def aTask():
  """Return aTask with minimal content."""
  task = Task({'Energy': 300.0}, {}, 333)
  return task


@pytest.fixture
def cpMock():
  """Return a Mock for the ConfigParser."""
  theCPMock = Mock()
  theCPMock.thisConfigDict = dict(configDict())

  def hasMock(*args, **kwargs):  # pylint: disable=unused-argument
    """Mock the configparser.has_option function."""
    return theCPMock.thisConfigDict.get(args[1])

  def mockConfig(*args, **kwargs):  # pylint: disable=unused-argument
    """Mock the configparser object."""
    assert args[0] == theScript.PP
    return theCPMock.thisConfigDict[args[1]]

  theCPMock.read = Mock()
  theCPMock.get = mockConfig
  theCPMock.has_option = hasMock
  return theCPMock


def test_meta(theChain):
  """Test meta data."""
  ret = theChain.meta(123, 'process', 555.5)
  assert {'ProdID': '123',
          'EvtType': 'process',
          'Energy': '555.5',
          'Machine': 'ee'} == ret
  theChain.ignoreMetadata = ['EvtType']
  ret = theChain.meta(123, 'process', 555.5)
  assert {'ProdID': '123',
          'Energy': '555.5',
          'Machine': 'ee'} == ret


def test_loadParameters(theChain, cpMock):
  """Test load parameters."""
  parameter = Mock()
  parameter.prodConfigFilename = None
  parameter.dumpConfigFile = None
  theChain.loadParameters(parameter)
  c = theChain

  parameter.prodConfigFilename = 'filename'

  with patch(SCP, new=Mock(return_value=cpMock)):
    c.loadParameters(parameter)
  assert c.prodGroup == "myProdGroup"
  assert c.detectorModel == "myDetectorModel"
  assert c.prodIDs == [123, 456]
  assert c.energies == [100, 200]
  assert c.eventsPerJobs == [1000, 2000]
  assert c.eventsInSplitFiles == [5000, 6000]

  assert c.moveStatus == 'Active'
  assert c.moveGroupSize == '11'

  cpMock.thisConfigDict['prodIDs'] = "123, 456, 789"
  with patch(SCP, new=Mock(return_value=cpMock)), \
       pytest.raises(AttributeError, match="Lengths of Processes"):
    c.loadParameters(parameter)

  cpMock.thisConfigDict['prodIDs'] = ''
  cpMock.has_option = Mock()
  cpMock.has_option.return_value = False
  with patch(SCP, new=Mock(return_value=cpMock)):
    c.loadParameters(parameter)
  assert c.prodIDs == [1, 1]
  assert c.cliRecoOption == '--Config.Tracking=Tracked'

  cpMock.thisConfigDict['eventsInSplitFiles'] = "1000"
  c._flags._spl = True
  with patch(SCP, new=Mock(return_value=cpMock)), \
       pytest.raises(AttributeError, match="Length of eventsInSplitFiles"):
    c.loadParameters(parameter)

  parameter.prodConfigFilename = None
  parameter.dumpConfigFile = True
  with patch(SCP, new=Mock(return_value=cpMock)), \
    pytest.raises(RuntimeError, match="^$"):
    c.loadParameters(parameter)

  parameter.prodConfigFilename = 'filename'
  parameter.dumpConfigFile = False
  cpMock.thisConfigDict['MoveStatus'] = 'Foo'
  with patch(SCP, new=Mock(return_value=cpMock)), \
       pytest.raises(AttributeError, match='MoveStatus can only be'):
    c.loadParameters(parameter)


def test_createMovingTransformation(theChain):
  """Test creating the moving productions."""
  theChain.outputSE = "Source"
  theChain.finalOutputSE = "Target"
  theChain.moveGroupSize = 13
  theChain._flags._rec = True
  theChain._flags._sim = True
  theChain._flags._moveDst = True
  theChain._flags._moveRec = False
  theChain._flags._moveSim = True
  theChain._flags._moves = True
  theChain._flags._dryRun = False
  with patch("DIRAC.TransformationSystem.Utilities.ReplicationTransformation.createDataTransformation") as moveMock:
    theChain.createMovingTransformation({'ProdID': 666}, 'MCReconstruction')
    parDict = dict(flavour='Moving',
                   targetSE='Target',
                   sourceSE='Source',
                   plugin='Broadcast',
                   metaKey='ProdID',
                   metaValue=666,
                   extraData={'Datatype': 'DST'},
                   tGroup='several',
                   groupSize=13,
                   enable=True,
                   )
    moveMock.assert_called_once_with(**parDict)

  with patch("DIRAC.TransformationSystem.Utilities.ReplicationTransformation.createDataTransformation") as moveMock:
    theChain.createMovingTransformation({'ProdID': 666}, 'MCSimulation')
    parDict = dict(flavour='Moving',
                   targetSE='Target',
                   sourceSE='Source',
                   plugin='BroadcastProcessed',
                   metaKey='ProdID',
                   metaValue=666,
                   extraData={'Datatype': 'SIM'},
                   tGroup='several',
                   groupSize=13,
                   enable=True,
                   )
    moveMock.assert_called_once_with(**parDict)

  theChain._flags._rec = True
  theChain._flags._moves = False
  theChain._flags._dryRun = False
  with patch("DIRAC.TransformationSystem.Utilities.ReplicationTransformation.createDataTransformation") as moveMock:
    theChain.createMovingTransformation({'ProdID': 666}, 'MCReconstruction')
    moveMock.assert_not_called()

  with pytest.raises(RuntimeError, match='ERROR creating Moving'):
    theChain.createMovingTransformation({'ProdID': 666}, "Split")

def test_setApplicationOptions(theChain, aTask):
  """Test setting the application options."""
  application = Mock()
  application.setSomeParameter = Mock()
  aTask.applicationOptions = {'foo': 'bar'}
  theChain.applicationOptions['AppName'] = {'SomeParameter': 'SomeValue', 'FE.foo': ['bar', 'baz'],
                                            'C_Repl': 'longValueWeDoNotwantToRepeat'}
  theChain._setApplicationOptions('AppName', application, aTask.applicationOptions)
  application.setSomeParameter.assert_called_once_with('SomeValue')
  application.setfoo.assert_called_once_with('bar')

  from ILCDIRAC.Interfaces.API.NewInterface.Applications.DelphesApp import DelphesApp
  application = DelphesApp()
  theChain.applicationOptions['AppName'] = {'SomeOtherParameter': 'SomeValue'}
  with pytest.raises(AttributeError, match='Cannot set'):
    theChain._setApplicationOptions('AppName', application)

def test_getProdInfoFromIDs(theChain):
  """Test getting theproduction information."""
  # successful
  theChain.prodIDs = [12345]
  trClientMock = Mock(name='trClient')
  trClientMock.getTransformation.return_value = S_OK({'EventsPerTask': 123})
  trMock = Mock(return_value=trClientMock)
  fcClientMock = Mock(name='fcClient')
  fcClientMock.findFilesByMetadata.return_value = S_OK(['/path/to/file'])
  fcClientMock.getDirectoryUserMetadata.return_value = S_OK({'EvtType': 'haha', 'Energy': 321})
  fcMock = Mock(return_value=fcClientMock)
  with patch('DIRAC.TransformationSystem.Client.TransformationClient.TransformationClient', new=trMock), \
       patch('DIRAC.Resources.Catalog.FileCatalogClient.FileCatalogClient', new=fcMock):
    theChain._getProdInfoFromIDs()
  assert theChain.eventsPerJobs == [123]
  assert theChain.processes == ['haha']
  assert theChain.energies == [321]

  # first exception
  theChain.prodIDs = []
  with pytest.raises(AttributeError, match='No prodIDs'):
    theChain._getProdInfoFromIDs()

  # second exception
  theChain.prodIDs = [12345]
  trClientMock = Mock(name='trClient')
  trClientMock.getTransformation.return_value = S_ERROR('No such prod')
  trMock = Mock(return_value=trClientMock)
  with patch('DIRAC.TransformationSystem.Client.TransformationClient.TransformationClient', new=trMock), \
       pytest.raises(AttributeError, match='No prodInfo found'):
    theChain._getProdInfoFromIDs()

  # third exception
  theChain.prodIDs = [12345]
  trClientMock = Mock(name='trClient')
  trClientMock.getTransformation.return_value = S_OK({'EventsPerTask': 123})
  trMock = Mock(return_value=trClientMock)
  fcClientMock = Mock(name='fcClient')
  fcClientMock.findFilesByMetadata.return_value = S_ERROR('No files found')
  fcMock = Mock(return_value=fcClientMock)
  with patch('DIRAC.TransformationSystem.Client.TransformationClient.TransformationClient', new=trMock), \
       patch('DIRAC.Resources.Catalog.FileCatalogClient.FileCatalogClient', new=fcMock), \
       pytest.raises(AttributeError, match='Could not find file'):
    theChain._getProdInfoFromIDs()

def test_createTransformations(theChain):
  """Test replcation transformation creation."""
  theChain.createMovingTransformation = Mock(name='MovingTrafo')
  taskDict = dict(MOVE_GEN=[{'move': 'gen'}],
                  MOVE_SPLIT=[{'move': 'split'}],
                  MOVE_SIM=[{'move': 'sim'}],
                  MOVE_REC=[{'move': 'rec'}],
                  MOVE_OVER=[{'move': 'over'}],
                )
  theChain.createTransformations(taskDict)
  theChain.createMovingTransformation.assert_any_call({'move': 'gen'}, 'MCGeneration')
  theChain.createMovingTransformation.assert_any_call({'move': 'split'}, 'MCGeneration')
  theChain.createMovingTransformation.assert_any_call({'move': 'sim'}, 'MCSimulation')
  theChain.createMovingTransformation.assert_any_call({'move': 'rec'}, 'MCReconstruction')
  theChain.createMovingTransformation.assert_any_call({'move': 'over'}, 'MCReconstruction_Overlay')

def test_addGenTask(theChain):
  """Test adding gen task."""
  taskDict = defaultdict(list)
  theChain.generatorApplication = 'delphesapp'
  theChain.addGenTask(taskDict, originalTask=Task({}, {}, 123))
  assert len(taskDict['GEN']) == 1

  taskDict = defaultdict(list)
  theChain.applicationOptions['delphesapp']['FE.additionalName'] = ['1', '2']
  theChain.applicationOptions['delphesapp']['steeringFile'] = ['steeringfile']
  theChain.addGenTask(taskDict, originalTask=Task({}, {}, 123))
  assert len(taskDict['GEN']) == 2
  assert taskDict['GEN'][0].taskName == '1'
  assert taskDict['GEN'][1].taskName == '2'

def test_createTaskDict_none(theChain):
  """Test createTaskDict function."""
  taskDict = theChain.createTaskDict(123456, 'ee_qq', 5000, 333, sinFile='file', nbTasks=222,
                                     eventsPerBaseFile=None, taskName='')
  for pType in ['GEN', 'SIM', 'REC', 'SPLIT']:
    assert not taskDict[pType]
  
def test_createTaskDict_gen(theChain):
  """Test createTaskDict function."""
  theChain._flags._gen = True
  taskDict = theChain.createTaskDict(123456, 'ee_qq', 5000, 333, sinFile='file', nbTasks=222,
                                     eventsPerBaseFile=None, taskName='')
  assert len(taskDict['GEN']) == 1
  assert taskDict['GEN'][0].genFile == 'file'
  assert taskDict['GEN'][0].nbTasks == 222
  assert taskDict['GEN'][0].meta == {'ProdID': '123456',
                                    'EvtType': 'ee_qq',
                                    'Energy': '5000',
                                    'Machine': 'ee',
                                    'NumberOfEvents': 333,
                                    }

@pytest.fixture
def theFlags():
  """Return the flags fixture."""
  return theScript.FCCDetProdChain.Flags()

def test_flags_init(theFlags):
  """Returns the flags constructor."""
  f = theFlags
  assert f._dryRun
  assert not f._gen
  assert not f._spl
  assert not f._sim
  assert not f._rec
  assert not f._over
  assert not f._moves
  assert not f._moveGen
  assert not f._moveSim
  assert not f._moveRec
  assert not f._moveDst

def test_flags_properties(theFlags):
  """Test the flags properties."""
  f = theFlags
  f._gen = True
  f._spl = True
  f._sim = True
  f._rec = False
  f._over = True
  assert f.dryRun
  assert f.gen
  assert f.spl
  assert f.sim
  assert not f.rec
  assert f.over
  f._dryRun = True
  f._moves = True
  f._moveRec = True
  assert f.move
  assert not f.moveGen
  assert not f.moveSim
  assert f.moveRec
  assert not f.moveDst
  f._dryRun = False
  f._moveGen = True
  f._moveSim = True
  f._moveRec = True
  f._moveDst = False
  assert f.move
  assert f.moveGen
  assert f.moveSim
  assert f.moveRec
  assert not f.moveDst

def test_flags_str(theFlags):
  """Test the flags string representation."""
  theFlags._gen = True
  theFlags._sim = True
  theFlags._rec = False
  theFlags._over = True
  flagStr = str(theFlags)
  assert flagStr == """

#Productions to create: Gen, Split, Sim, Rec, RecOver
ProdTypes = Gen, Sim, RecOver

move = False

#Datatypes to move: Gen, Sim, Rec, Dst
MoveTypes = \n"""

def test_loadFlags(theFlags):
  """Test loading the flags from config."""
  myConfig = six.moves.configparser.ConfigParser()
  myConfig.add_section(theScript.PRODUCTION_PARAMETERS)
  myConfig.set(theScript.PRODUCTION_PARAMETERS, 'ProdTypes', 'Gen, Sim,Rec')
  myConfig.set(theScript.PRODUCTION_PARAMETERS, 'move', 'False')
  myConfig.set(theScript.PRODUCTION_PARAMETERS, 'MoveTypes', 'gen, dst')
  theFlags.loadFlags(myConfig)
  f = theFlags
  assert f.gen
  assert f.sim
  assert f.rec
  assert not f.over
  assert f._moveGen
  assert not f._moveSim
  assert not f._moveRec
  assert f._moveDst
  myConfig.set(theScript.PRODUCTION_PARAMETERS, 'MoveTypes', 'gen, dst, badType')
  with pytest.raises(AttributeError, match='badType'):
    theFlags.loadFlags(myConfig)

@pytest.fixture
def theParams():
  """Return the Params fixture."""
  return theScript._Params()

def test_params_init(theParams):
  """Test the Params constructor."""
  assert theParams.prodConfigFilename is None
  assert not theParams.dumpConfigFile
  assert theParams.dryRun
  assert theParams.additionalName == ''

def test_params_setters(theParams):
  """Test the Params setters."""
  with patch("%s.os.path.exists" % THE_SCRIPT, new=Mock(return_value=True)):
    assert theParams.setProdConf('myconf')['OK']

  assert theParams.prodConfigFilename, 'myconf'
  assert theParams.setDumpConf('_')['OK']
  assert theParams.dumpConfigFile
  assert theParams.setEnable('_')['OK']
  assert not theParams.dryRun
  assert theParams.setAddName('addName')['OK']
  assert theParams.additionalName, 'addName'

# -------------------------------------------------------------------------

def test_basepath(theChain):
  theChain.machine = 'ee'
  theChain.campaign = 'winter2023'

  theChain._basepath = ''
  with patch("DIRAC.ConfigurationSystem.Client.Helpers.Operations.Operations.getValue", new=Mock(return_value="/fcc/ee/")):
    basepath = theChain.basepath
  assert basepath == "/fcc/ee/winter2023/"

  theChain._basepath = "/fcc/hh/"
  basepath = theChain.basepath
  assert basepath == "/fcc/hh/winter2023/"

def test_createGeneratorApplication(theChain, aTask):
    from ILCDIRAC.Interfaces.API.NewInterface.Applications import DelphesApp
    theChain.generatorApplication = 'delphesapp'
    aTask.datatype = 'sim'
    genApp = theChain.createGeneratorApplication(aTask)
    assert isinstance(genApp, DelphesApp)
#    assert genApp.datatype == aTask.datatype

@pytest.fixture
def pMockMod():
  """Return Module for ProductionJob."""
  pMockMod = Mock()
  pjMock = Mock(name="ProductionJob")
  pMockMod.return_value = pjMock
  pjMock.getMetadata.return_value = {}
  return pMockMod

def test_createGenProduction(theChain, aTask, pMockMod):
  """Test creating the generation production."""
  theChain._basepath = '/fcc/ee/'
  with patch("ILCDIRAC.Interfaces.API.NewInterface.ProductionJob.ProductionJob", new=pMockMod):
    aTask.parameterDict['process'] = 'qqbar'
    aTask.meta = {'Energy': '240',
                  'EvtType': 'ZH_incl',
                  'Machine': 'ee',
                  'NumberOfEvents': 1500,
                  'ProdID': '1'}
    aTask.eventsPerJob = 100
    retMeta = theChain.createGenerationProduction(aTask)
  assert retMeta == {}

def test_createGenProduction2(theChain, aTask, pMockMod):
  """Test creating the generation production, with a processing step after generation"""
  theChain._basepath = '/fcc/ee/'
  with patch("ILCDIRAC.Interfaces.API.NewInterface.ProductionJob.ProductionJob", new=pMockMod):
    aTask.parameterDict['process'] = 'qqbar'
    aTask.meta = {'Energy': '240',
                  'EvtType': 'ZH_incl',
                  'Machine': 'ee',
                  'NumberOfEvents': 1500,
                  'ProdID': '1'}
    aTask.eventsPerJob = 100
    theChain.processingAfterGen = 'delphesapp'
    retMeta = theChain.createGenerationProduction(aTask)
  assert retMeta == {}

# -------------------------------------------------------------------------

def test_createKKMCApplication(theChain, aTask, cpMock):
  """Test creating the kkmc application."""
  from ILCDIRAC.Interfaces.API.NewInterface.Applications import KKMC

  parameter = Mock(name="ParameterMock")
  parameter.dumpConfigFile = False
  with patch(SCP, new=Mock(return_value=cpMock)):
    theChain.loadParameters(parameter)

  aTask.meta = {'Energy': '240',
                'EvtType': 'ZH_incl',
                'Machine': 'ee',
                'NumberOfEvents': 1500,
                'ProdID': '1'}
  aTask.eventsPerJob = 100

  ret = theChain.createKKMCApplication(aTask)
  assert isinstance(ret, KKMC)
  assert ret.datatype == 'hepmc'
  assert ret.version == 'mySoftwareVersion'

def test_createBabayagaApplication(theChain, aTask, cpMock):
  """Test creating the babayaga application."""
  from ILCDIRAC.Interfaces.API.NewInterface.Applications import Babayaga

  parameter = Mock(name="ParameterMock")
  parameter.dumpConfigFile = False
  with patch(SCP, new=Mock(return_value=cpMock)):
    theChain.loadParameters(parameter)

  aTask.meta = {'Energy': '240',
                'EvtType': 'ZH_incl',
                'Machine': 'ee',
                'NumberOfEvents': 1500,
                'ProdID': '1'}
  aTask.eventsPerJob = 100

  ret = theChain.createBabayagaApplication(aTask)
  assert isinstance(ret, Babayaga)
  assert ret.datatype == 'lhef'
  assert ret.version == 'mySoftwareVersion'

def test_createBhlumiApplication(theChain, aTask, cpMock):
  """Test creating the bhlumi application."""
  from ILCDIRAC.Interfaces.API.NewInterface.Applications import Bhlumi

  parameter = Mock(name="ParameterMock")
  parameter.dumpConfigFile = False
  with patch(SCP, new=Mock(return_value=cpMock)):
    theChain.loadParameters(parameter)

  aTask.meta = {'Energy': '240',
                'EvtType': 'ZH_incl',
                'Machine': 'ee',
                'NumberOfEvents': 1500,
                'ProdID': '1'}
  aTask.eventsPerJob = 100

  ret = theChain.createBhlumiApplication(aTask)
  assert isinstance(ret, Bhlumi)
  assert ret.datatype == 'lhef'
  assert ret.version == 'mySoftwareVersion'

def test_createDelphesApplication(theChain, aTask, cpMock):
  """Test creating the delphes application."""
  from ILCDIRAC.Interfaces.API.NewInterface.Applications import DelphesApp

  parameter = Mock(name="ParameterMock")
  parameter.dumpConfigFile = False
  with patch(SCP, new=Mock(return_value=cpMock)):
    theChain.loadParameters(parameter)

  aTask.meta = {'Energy': '240',
                'EvtType': 'ZH_incl',
                'Machine': 'ee',
                'NumberOfEvents': 1500,
                'ProdID': '1'}
  aTask.genFile = 'p8_ee_ZZ_ecm240.cmd'
  aTask.eventsPerJob = 100

  ret = theChain.createDelphesApplication(aTask)
  assert isinstance(ret, DelphesApp)
  assert ret.datatype == 'delphes'
  assert ret.version == 'mySoftwareVersion'

def test_createGaudiApplication(theChain, aTask, cpMock):
  """Test creating the delphes application."""
  from ILCDIRAC.Interfaces.API.NewInterface.Applications import GaudiApp

  parameter = Mock(name="ParameterMock")
  parameter.dumpConfigFile = False
  with patch(SCP, new=Mock(return_value=cpMock)):
    theChain.loadParameters(parameter)
  aTask.meta = {'Energy': '240',
                'EvtType': 'ZH_incl',
                'Machine': 'ee',
                'NumberOfEvents': 1500,
                'ProdID': '1'}
  aTask.applicationOptions = {'GaudiWorkFlow': 'fastsim'}
  aTask.eventsPerJob = 100
  aTask.genFile = 'p8_ee_ZZ_ecm240.cmd'

  ret = theChain.createGaudiApplication(aTask)
  assert isinstance(ret, GaudiApp)
  assert ret.datatype == 'delphes'
  assert ret.version == 'mySoftwareVersion'

def test_createGaudiApplication_2(theChain, aTask, cpMock):
  """Test creating the delphes application."""
  from ILCDIRAC.Interfaces.API.NewInterface.Applications import GaudiApp

  parameter = Mock(name="ParameterMock")
  parameter.dumpConfigFile = False
  with patch(SCP, new=Mock(return_value=cpMock)):
    theChain.loadParameters(parameter)

  aTask.meta = {'Energy': '240',
                'EvtType': 'ZH_incl',
                'Machine': 'ee',
                'NumberOfEvents': 1500,
                'ProdID': '1'}
  aTask.applicationOptions = {'GaudiWorkFlow': 'fullsim'}
  aTask.eventsPerJob = 100

  ret = theChain.createGaudiApplication(aTask)
  assert not ret.datatype
  assert isinstance(ret, GaudiApp)
  assert ret.version == 'mySoftwareVersion'

def test_createWhizard2Application(theChain, aTask, cpMock):
  """Test creating the delphes application."""
  from ILCDIRAC.Interfaces.API.NewInterface.Applications import Whizard2

  parameter = Mock(name="ParameterMock")
  parameter.dumpConfigFile = False
  with patch(SCP, new=Mock(return_value=cpMock)):
    theChain.loadParameters(parameter)

  aTask.meta = {'Energy': '240',
                'EvtType': 'ZH_incl',
                'Machine': 'ee',
                'NumberOfEvents': 1500,
                'ProdID': '1'}
  aTask.genFile = 'ee_ZHH_1500gev_polp80.sin'
  aTask.eventsPerJob = 100

  ret = theChain.createWhizard2Application(aTask)
  assert isinstance(ret, Whizard2)
  assert ret.datatype == "stdhep"
  assert ret.version == 'mySoftwareVersion'