001package jmri.jmrit.operations.automation.actions;
002
003import java.io.File;
004
005import org.slf4j.Logger;
006import org.slf4j.LoggerFactory;
007
008import jmri.InstanceManager;
009import jmri.jmrit.operations.locations.Location;
010import jmri.jmrit.operations.locations.LocationManager;
011import jmri.jmrit.operations.setup.Control;
012import jmri.jmrit.operations.setup.Setup;
013import jmri.jmrit.operations.trains.*;
014import jmri.jmrit.operations.trains.csv.TrainCsvSwitchLists;
015import jmri.jmrit.operations.trains.excel.TrainCustomManifest;
016import jmri.jmrit.operations.trains.excel.TrainCustomSwitchList;
017
018public class RunSwitchListChangesAction extends Action {
019
020    private static final int _code = ActionCodes.RUN_SWITCHLIST_CHANGES;
021    protected static final boolean IS_CHANGED = true;
022
023    @Override
024    public int getCode() {
025        return _code;
026    }
027
028    @Override
029    public String getName() {
030        return Bundle.getMessage("RunSwitchListChanges");
031    }
032
033    @Override
034    public void doAction() {
035        doAction(IS_CHANGED);
036    }
037
038    /**
039     * Creates a custom switch list for each location that is selected and there's
040     * new work for that location.
041     * <p>
042     * common code see RunSwitchListAction.java
043     *
044     * @param isChanged if set true only locations with changes will get a custom
045     *                  switch list.
046     */
047    protected void doAction(boolean isChanged) {
048        if (getAutomationItem() != null) {
049            if (!Setup.isGenerateCsvSwitchListEnabled()) {
050                log.warn("Generate CSV Switch List isn't enabled!");
051                finishAction(false);
052                return;
053            }
054            // we do need one of these!
055            if (!InstanceManager.getDefault(TrainCustomSwitchList.class).excelFileExists()) {
056                log.warn("Manifest creator file not found!, directory name: {}, file name: {}",
057                        InstanceManager.getDefault(TrainCustomSwitchList.class).getDirectoryName(),
058                        InstanceManager.getDefault(TrainCustomSwitchList.class).getFileName());
059                finishAction(false);
060                return;
061            }
062            setRunning(true);
063            TrainSwitchLists trainSwitchLists = new TrainSwitchLists();
064            TrainCsvSwitchLists trainCsvSwitchLists = new TrainCsvSwitchLists();
065            // check that both the Excel custom manifest and custom switch lists aren't busy
066            // with other work
067            // We've found that on some OS only one copy of Excel can be running at a time
068            // this can wait thread
069            if (!InstanceManager.getDefault(TrainCustomManifest.class).checkProcessReady()) {
070                log.warn(
071                        "Timeout waiting for excel manifest program to complete previous operation, timeout value: {} seconds",
072                        Control.excelWaitTime);
073            }
074            // this can wait thread
075            if (!InstanceManager.getDefault(TrainCustomSwitchList.class).checkProcessReady()) {
076                log.warn(
077                        "Timeout waiting for excel switch list program to complete previous operation, timeout value: {} seconds",
078                        Control.excelWaitTime);
079            }
080            if (InstanceManager.getDefault(TrainCustomSwitchList.class).doesCommonFileExist()) {
081                log.warn("Switch List CSV common file exists!");
082            }
083            for (Location location : InstanceManager.getDefault(LocationManager.class).getUniqueLocationsByNameList()) {
084                if (location.isSwitchListEnabled() &&
085                        (!isChanged || location.getStatus().equals(Location.MODIFIED))) {
086                    File csvFile = trainCsvSwitchLists.buildSwitchList(location);
087                    // also build the regular switch lists so they can be used
088                    trainSwitchLists.buildSwitchList(location);
089                    if (csvFile == null || !csvFile.exists()) {
090                        log.error("CSV switch list file was not created for location {}", location.getName());
091                        finishAction(false);
092                        return;
093                    }
094                    location.setStatus(Location.PRINTED);
095                    location.setSwitchListState(Location.SW_PRINTED);
096                    InstanceManager.getDefault(TrainCustomSwitchList.class).addCsvFile(csvFile);
097                    log.info("Queued switch list CSV file location ({}) for custom processing", location.getName());
098                }
099            }
100            // Processes the CSV Manifest files using an external custom program.
101            boolean status = InstanceManager.getDefault(TrainCustomSwitchList.class).process();
102            if (status) {
103                try {
104                 // wait up to 60 seconds per file
105                    status = InstanceManager.getDefault(TrainCustomSwitchList.class).waitForProcessToComplete(); 
106                } catch (InterruptedException e) {
107                    // TODO Auto-generated catch block
108                    log.error("Thread interrupeted while waiting", e);
109                }
110            } else {
111                log.info("No switch list changes found");
112            }
113            // set trains switch lists printed
114            InstanceManager.getDefault(TrainManager.class).setTrainsSwitchListStatus(Train.PRINTED);
115            finishAction(status);
116        }
117    }
118
119    @Override
120    public void cancelAction() {
121        // no cancel for this action
122    }
123
124    private final static Logger log = LoggerFactory.getLogger(RunSwitchListChangesAction.class);
125
126}