001package jmri.jmrix.openlcb;
002
003import java.util.HashMap;
004import java.util.Map;
005
006import jmri.InstanceManager;
007import jmri.ShutDownManager;
008import jmri.jmrix.openlcb.configurexml.OlcbEventNameStoreXml;
009
010import org.openlcb.EventID;
011import org.openlcb.EventNameStore;
012
013/**
014 * JMRI's implementation of part of the OpenLcb EventNameStore interface.
015 *
016 * @author Bob Jacobsen Copyright (C) 2024
017 */
018public final class OlcbEventNameStore implements EventNameStore {
019
020    public OlcbEventNameStore() {
021
022        readDetails();
023        
024        initShutdownTask();
025    }
026
027    private final Map<String, EventID> nameToId = new HashMap<>();
028    private final Map<EventID, String> idToName = new HashMap<>();
029    public boolean dirty = false;
030
031    /**
032     * @param eventID The EventID being searched for
033     * @return The name associated with that EventID or the event ID in dotted hex
034     */
035    @Override
036    public String getEventName(EventID eventID) {
037        var name = idToName.get(eventID);
038        if (name == null || name.isEmpty()) return eventID.toShortString();
039        return name;
040    }
041    
042    /**
043     * @param eventID The EventID being searched for
044     * @return true if there is an associated name
045     */
046    public boolean hasEventName(EventID eventID) {
047        var name = idToName.get(eventID);
048        if (name == null || name.isEmpty()) return false;
049        return true;
050    }
051
052    /**
053     * @param name The event name being searched for
054     * @return The EventID associated with that name or an event ID constructed from the input
055     */
056    @Override
057    public EventID getEventID(String name) {
058        var eid = nameToId.get(name);
059        if (eid == null) return new EventID(name);
060        return eid;    
061    }
062
063    /**
064     * @param name The event name being searched for
065     * @return true if an EventID is associated with that name
066     */
067    public boolean hasEventID(String name) {
068        var eid = nameToId.get(name);
069        if (eid == null) return false;
070        return true;    
071    }
072
073    /**
074     * Create a new name to/from EventID association
075     * @param eventID associated EventID
076     * @param name  associated name
077     */
078    public void addMatch(EventID eventID, String name) {
079        nameToId.put(name, eventID);
080        idToName.put(eventID, name);
081        log.trace("setting dirty true");
082        dirty = true;
083    }
084
085    /**
086     * Get all the EventIDs available
087     * @return Set of all available EventIDs
088     */
089    public java.util.Set<EventID> getMatches() {
090        return idToName.keySet();        
091    }
092
093    public void readDetails() {
094        log.debug("reading Event Name Details");
095        new OlcbEventNameStoreXml(this,"EventNames.xml").load();  // NOI18N
096        log.debug("...done reading Event Name details");
097    }
098
099    private Runnable shutDownTask = null;
100
101    protected void initShutdownTask(){
102        // Create shutdown task to save
103        log.debug("Register ShutDown task");
104        if (this.shutDownTask == null) {
105            this.shutDownTask = () -> {
106                // Save event name details prior to exit, if necessary
107                log.debug("Start writing event name details...");
108                try {
109                    writeEventNameDetails();
110                } catch (java.io.IOException ioe) {
111                    log.error("Exception writing event name", ioe);
112                }
113            };
114            InstanceManager.getDefault(ShutDownManager.class).register(this.shutDownTask);
115        }
116    }
117
118    /**
119     * De-register the Shutdown task.
120     */
121    public void deregisterShutdownTask(){
122        log.debug("Deregister ShutDown task");
123        if ( shutDownTask != null ) {
124            InstanceManager.getDefault(ShutDownManager.class).deregister(shutDownTask);
125        }
126    }
127
128    public void writeEventNameDetails() throws java.io.IOException {
129        log.debug("storing event name map {}", dirty);
130        if (this.dirty) {
131            new OlcbEventNameStoreXml(this,"EventNames.xml").store();  // NOI18N
132            this.dirty = false;
133            log.debug("...done writing event name details");
134        }
135    }
136
137
138    private static final org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(OlcbEventNameStore.class);
139
140}