/*
 *  Licensed to the Apache Software Foundation (ASF) under one
 *  or more contributor license agreements.  See the NOTICE file
 *  distributed with this work for additional information
 *  regarding copyright ownership.  The ASF licenses this file
 *  to you under the Apache License, Version 2.0 (the
 *  "License"); you may not use this file except in compliance
 *  with the License.  You may obtain a copy of the License at
 *
 *        http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing,
 *  software distributed under the License is distributed on an
 *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 *  KIND, either express or implied.  See the License for the
 *  specific language governing permissions and limitations
 *  under the License.
 */
package org.apache.isis.testing.fixtures.applib.services;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import javax.inject.Inject;
import javax.inject.Named;

import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Primary;
import org.springframework.context.event.EventListener;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Service;

import org.apache.isis.applib.annotation.OrderPrecedence;
import org.apache.isis.applib.services.inject.ServiceInjector;
import org.apache.isis.core.config.IsisConfiguration;
import org.apache.isis.core.config.environment.IsisSystemEnvironment;
import org.apache.isis.applib.services.iactnlayer.InteractionService;
import org.apache.isis.core.metamodel.events.MetamodelEvent;
import org.apache.isis.testing.fixtures.applib.clock.clock.Clock;
import org.apache.isis.testing.fixtures.applib.clock.clock.FixtureClock;
import org.apache.isis.testing.fixtures.applib.fixturescripts.FixtureScript;
import org.apache.isis.testing.fixtures.applib.fixturescripts.FixtureScripts;

import lombok.extern.log4j.Log4j2;

/**
 * @since 2.0 {@index}
 */
@Service
@Named("isis.testing.fixtures.FixturesLifecycleService")
@Order(OrderPrecedence.MIDPOINT)
@Primary
@Qualifier("Default")
@Log4j2
public class FixturesLifecycleService {

    @SuppressWarnings("unused")

    @Inject
    private InteractionService interactionService; // depends on relationship
    @Inject
    private IsisSystemEnvironment isisSystemEnvironment;
    @Inject
    private IsisConfiguration isisConfiguration;
    @Inject
    private ServiceInjector serviceInjector;
    @Inject
    private FixtureScripts fixtureScripts;

    private FixtureScript initialFixtureScript;


    @PostConstruct
    public void postConstruct() {

        // a bit of a workaround, but required if anything in the metamodel (for example, a
        // ValueSemanticsProvider for a date value type) needs to use the Clock singleton
        // we do this after loading the services to allow a service to prime a different clock
        // implementation (eg to use an NTP time service).
        if (isisSystemEnvironment.isPrototyping() && !Clock.isInitialized()) {
            FixtureClock.initialize();
        }

        final Class<?> initialScript = isisConfiguration.getTesting().getFixtures().getInitialScript();
        if (initialScript != null && FixtureScript.class.isAssignableFrom(initialScript)) {
            try {
                initialFixtureScript = (FixtureScript) initialScript.newInstance();
                serviceInjector.injectServicesInto(initialFixtureScript);
            } catch (InstantiationException | IllegalAccessException e) {
                initialFixtureScript = null;
            }
        }
    }

    @EventListener(MetamodelEvent.class)
    public void onMetamodelEvent(final MetamodelEvent event) {

        log.debug("received metamodel event {}", event);

        if (event.isPostMetamodel()
                && initialFixtureScript != null) {

            log.info("install initial fixtures from script {}", initialFixtureScript.getFriendlyName());
            fixtureScripts.run(initialFixtureScript);
        }

    }


    @PreDestroy
    public void preDestroy() {

    }

}

@@ -893,71 +893,49 @@
 java
-x.annotation.PostConstruct;%0Aimport javax.annotation.PreDestroy;
+.lang.reflect.InvocationTargetException;%0A
 %0Aimp
@@ -1466,318 +1466,39 @@
 ore.
-config.environment.IsisSystemEnvironment;%0Aimport org.apache.isis.applib.services.iactnlayer.InteractionService;%0Aimport org.apache.isis.core.metamodel.events.MetamodelEvent;%0Aimport org.apache.isis.testing.fixtures.applib.clock.clock.Clock;%0Aimport org.apache.isis.testing.fixtures.applib.clock.clock.FixtureClock
+metamodel.events.MetamodelEvent
 ;%0Aim
@@ -1647,24 +1647,52 @@
 reScripts;%0A%0A
+import lombok.SneakyThrows;%0A
 import lombo
@@ -1966,304 +1966,21 @@
     
-@Inject%0A    private InteractionService interactionService; // depends on relationship%0A    @Inject%0A    private IsisSystemEnvironment isisSystemEnvironment;%0A    @Inject%0A    private IsisConfiguration isisConfiguration;%0A    @Inject%0A    private ServiceInjector serviceInjector;%0A    @Inject%0A    
 private
+ final
  Fix
@@ -2061,25 +2061,17 @@
 t;%0A%0A
-%0A
     @
-PostConstru
+Inje
 ct%0A 
@@ -2084,213 +2084,88 @@
 lic 
-void postConstruct() %7B%0A%0A        // a bit of a workaround, but required if anything in the metamodel (for example, a%0A        // ValueSemanticsProvider for a date value type) needs to use the Clock singlet
+FixturesLifecycleService(%0A            final IsisConfiguration isisConfigurati
 on
+,
 %0A   
@@ -2173,281 +2173,97 @@
     
-// we do this after loading the services to allow a service to prime a different clock%0A        // implementation (eg to use an NTP time service).%0A        if (isisSystemEnvironment.isPrototyping() && !Clock.isInitialized()) %7B%0A            FixtureClock.initialize();%0A        %7D
+    final FixtureScripts fixtureScripts) %7B%0A%0A        this.fixtureScripts = fixtureScripts;
 %0A%0A  
@@ -2547,94 +2547,45 @@
 ipt.
-newInstance();%0A                serviceInjector.injectServicesInto(initialFixtureScript
+getDeclaredConstructor().newInstance(
 );%0A 
@@ -2652,16 +2652,68 @@
 ception 
+%7C NoSuchMethodException %7C InvocationTargetException 
 e) %7B%0A   
@@ -3209,65 +3209,8 @@
   %7D%0A
-%0A    %7D%0A%0A%0A    @PreDestroy%0A    public void preDestroy() %7B%0A%0A
     

simplifies FixturesLifecycleService