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    public String getEventName(EventID eventID) {
036        var name = idToName.get(eventID);
037        if (name == null || name.isEmpty()) return eventID.toShortString();
038        return name;
039    }
040    
041    /**
042     * @param eventID The EventID being searched for
043     * @return true if there is an associated name
044     */
045    public boolean hasEventName(EventID eventID) {
046        var name = idToName.get(eventID);
047        if (name == null || name.isEmpty()) return false;
048        return true;
049    }
050
051    /**
052     * @param name The event name being searched for
053     * @return The EventID associated with that name or an event ID constructed from the input
054     */
055    @Override
056    public EventID getEventID(String name) {
057        var eid = nameToId.get(name);
058        if (eid == null) return new EventID(name);
059        return eid;    
060    }
061
062    /**
063     * @param name The event name being searched for
064     * @return true if an EventID is associated with that name
065     */
066    public boolean hasEventID(String name) {
067        var eid = nameToId.get(name);
068        if (eid == null) return false;
069        return true;    
070    }
071
072    /**
073     * Create a new name to/from EventID association
074     * @param eventID associated EventID
075     * @param name  associated name
076     */
077    public void addMatch(EventID eventID, String name) {
078        nameToId.put(name, eventID);
079        idToName.put(eventID, name);
080        log.trace("setting dirty true");
081        dirty = true;
082    }
083
084    /**
085     * Get all the EventIDs available
086     * @return Set of all available EventIDs
087     */
088    public java.util.Set<EventID> getMatches() {
089        return idToName.keySet();        
090    }
091
092    public void readDetails() {
093        log.debug("reading Event Name Details");
094        new OlcbEventNameStoreXml(this,"EventNames.xml").load();  // NOI18N
095        log.debug("...done reading Event Name details");
096    }
097
098    private Runnable shutDownTask = null;
099
100    protected void initShutdownTask(){
101        // Create shutdown task to save
102        log.debug("Register ShutDown task");
103        if (this.shutDownTask == null) {
104            this.shutDownTask = () -> {
105                // Save event name details prior to exit, if necessary
106                log.debug("Start writing event name details...");
107                try {
108                    writeEventNameDetails();
109                } catch (java.io.IOException ioe) {
110                    log.error("Exception writing event name", ioe);
111                }
112            };
113            InstanceManager.getDefault(ShutDownManager.class).register(this.shutDownTask);
114        }
115    }
116
117    /**
118     * De-register the Shutdown task.
119     */
120    public void deregisterShutdownTask(){
121        log.debug("Deregister ShutDown task");
122        if ( shutDownTask != null ) {
123            InstanceManager.getDefault(ShutDownManager.class).deregister(shutDownTask);
124        }
125    }
126
127    public void writeEventNameDetails() throws java.io.IOException {
128        log.debug("storing event name map {}", dirty);
129        if (this.dirty) {
130            new OlcbEventNameStoreXml(this,"EventNames.xml").store();  // NOI18N
131            this.dirty = false;
132            log.debug("...done writing event name details");
133        }
134    }
135
136
137    private static final org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(OlcbEventNameStore.class);
138
139}