 /**************************************************************************
 OmegaT - Computer Assisted Translation (CAT) tool 
          with fuzzy matching, translation memory, keyword search, 
          glossaries, and translation leveraging into updated projects.

 Copyright (C) 2021 Thomas Cordonnier
               Home page: http://www.omegat.org/
               Support center: http://groups.yahoo.com/group/OmegaT/

 This file is part of OmegaT.

 OmegaT is free software: you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
 the Free Software Foundation, either version 3 of the License, or
 (at your option) any later version.

 OmegaT is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU General Public License for more details.

 You should have received a copy of the GNU General Public License
 along with this program.  If not, see <http://www.gnu.org/licenses/>.
 **************************************************************************/

package org.omegat.core.data;

import java.io.File;
import java.util.Map;
import java.util.concurrent.ConcurrentSkipListMap;

import org.omegat.core.Core;
import org.omegat.util.DirectoryMonitor;
import org.omegat.util.Log;
 
abstract class MonitoredDirectoryMap<K,V> {
    private Map<K,V> theMap = new ConcurrentSkipListMap<>();
    private DirectoryMonitor monitor;
    
    public MonitoredDirectoryMap(String root) {
        File fRoot = new File(root);
        if (fRoot.exists()) {
            monitor = new DirectoryMonitor(fRoot, (File file) -> {
                K key = MonitoredDirectoryMap.this.accept(file);
                if (key == null) return;
                
                // create new translation memories map
                if (file.exists())
                    try {
                        theMap.put(key, MonitoredDirectoryMap.this.load(file));
                    } catch (Exception e) {
                        String filename = file.getPath();
                        Log.logErrorRB(e, "TF_TM_LOAD_ERROR", filename);
                        Core.getMainWindow().displayErrorRB(e, "TF_TM_LOAD_ERROR", filename);
                    }
                else {
                    theMap.remove(key);
                    MonitoredDirectoryMap.this.onDelete(file);
                }
            });
            monitor.checkChanges();
            monitor.start();
        }
    }
    
    public Map<K,V> getMap() { return theMap; }
    
    public void clear() { theMap.clear(); }
    
    public void end() { if (monitor != null) monitor.fin(); }
    
    /** 
     * Whenever this file should be added:
     * @return null if file should be refused, else its key
     **/
    public abstract K accept(File f);
    
    public abstract V load(File f) throws Exception;
    
    /** Called when a file is deleted, to be overridden if you need to do more than only delete in the map **/
    public void onDelete(File f) {
    }
    
}
