/*
 * Copyright 2015-2017 the original author or authors.
 *
 * Licensed 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.lastaflute.job.subsidiary;

import java.time.LocalDateTime;

/**
 * @author jflute
 * @since 0.4.1 (2017/03/20 Monday)
 */
public interface CrossVMHook {

    // e.g.
    // _/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
    // public CrossVMState hookBeginning(ReadableJobAttr jobAttr, LocalDateTime beginTime) {
    //     OptionalThing<JobExecution> jobExecution = jobExecutionBhv.selectByUniqueOf(job.getJobUnique().get());
    //     if (jobExecution.isPresent()) { // concurrent
    //         ConcurrentJobStopper stopper = new ConcurrentJobStopper();
    //         return stopper.stopIfNeeds(...).map(result -> { // quit (or exception)
    //             return asQuitState();
    //         }).orElseGet(() -> { // wait
    //             waitForEndingBySomething();
    //             return asNormalState();
    //         });
    //     } else {
    //         return asNormalExecution();
    //     }
    // }
    // private CrossVMState asQuitState() {
    //     return new CrossVMState().asQuit();
    // }
    // private CrossVMState asNormalState() {
    //     JobExecution jobExecution = jobExecutionBhv.insert(...);
    //     return new CrossVMState().withAttribute("jobExecutionId", jobExecution.getJobExecutionId());
    // }
    // _/_/_/_/_/_/_/_/_/_/
    CrossVMState hookBeginning(ReadableJobAttr jobAttr, LocalDateTime beginTime);

    // e.g.
    // _/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
    // public void hookEnding(ReadableJobAttr jobAttr, CrossVMState state) {
    //     Long jobExecutionId = state.getAttribute("jobExecutionId", Long.class).get();
    //     jobExecutionBhv.delete(...);
    // }
    // _/_/_/_/_/_/_/_/_/_/
    void hookEnding(ReadableJobAttr jobAttr, CrossVMState state, LocalDateTime endTime);
}

@@ -1034,21 +1034,23 @@
 %3CJobExec
-ution
+Control
 %3E jobExe
@@ -1042,37 +1042,39 @@
 Control%3E jobExec
-ution
+Control
  = jobExecutionB
@@ -1063,29 +1063,31 @@
 ol = jobExec
-ution
+Control
 Bhv.selectBy
@@ -1144,21 +1144,23 @@
 (jobExec
-ution
+Control
 .isPrese
@@ -1788,21 +1788,23 @@
 Exec
-ution
+Control
  jobExec
 utio
@@ -1799,21 +1799,23 @@
  jobExec
-ution
+Control
  = jobEx
@@ -1812,29 +1812,31 @@
 ol = jobExec
-ution
+Control
 Bhv.insert(.
@@ -1895,29 +1895,31 @@
 ute(%22jobExec
-ution
+Control
 Id%22, jobExec
@@ -1918,21 +1918,23 @@
  jobExec
-ution
+Control
 .getJobE
@@ -1936,21 +1936,23 @@
 tJobExec
-ution
+Control
 Id());%0A 
@@ -1983,24 +1983,272 @@
 /_/_/_/_/_/%0A
+    /**%0A     * @param jobAttr The object that can provide attributes of job. (NotNull)%0A     * @param beginTime The date-time of job beginning. (NotNull)%0A     * @return The state object of hook runtime, can be used at ending hook. (NotNull)%0A     */%0A
     CrossVMS
@@ -2522,21 +2522,23 @@
  jobExec
-ution
+Control
 Id = sta
@@ -2561,21 +2561,23 @@
 %22jobExec
-ution
+Control
 Id%22, Lon
@@ -2610,21 +2610,23 @@
  jobExec
-ution
+Control
 Bhv.dele
@@ -2667,24 +2667,272 @@
 /_/_/_/_/_/%0A
+    /**%0A     * @param jobAttr The object that can provide attributes of job. (NotNull)%0A     * @param state The state object of hook runtime, can be used at ending hook. (NotNull)%0A     * @param endTime The date-time of job ending. (NotNull)%0A     */%0A
     void hoo

write javadoc of CrossVMHook