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