/**
 **
 ** ModelRegex.java - Regular expression model for pattern-based object name matching
 **
 ** Copyright (C) 2024 Elphel, Inc.
 **
 ** -----------------------------------------------------------------------------**
 **
 **  ModelRegex.java 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.
 **
 **  This program 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 com.elphel.imagej.orthomosaic;

import java.io.File;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.nio.file.attribute.FileTime;
import java.text.SimpleDateFormat;
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Collection;
import java.util.Date;
import java.util.HashMap;
import java.util.regex.Pattern;

import ij.Prefs;

public class ModelRegex implements Serializable{
	private static final long serialVersionUID = 1L;	
	public String name;
	public String regex;
	public LocalDateTime start_date;
	public LocalDateTime end_date;

	public ModelRegex(
			String        name,
			String        regex,
			LocalDateTime start_date,
			LocalDateTime end_date) {
		this.name =       name;
		this.regex =      regex;
		this.start_date = start_date;
		this.end_date =   end_date;
	}
	
	private void writeObject(ObjectOutputStream oos) throws IOException {
		oos.defaultWriteObject();
	}
	private void readObject(ObjectInputStream ois) throws ClassNotFoundException, IOException {
		ois.defaultReadObject();
	}
	
	public String replaceByFilter (String path) {
		String model_path = OrthoMap.getModelPathFromPath(path);
		File model_dir = (new File(model_path)); // .getParentFile();
		if (!model_dir.exists() || !model_dir.isDirectory()) {
			return null;
		}
		File [] files = model_dir.listFiles();
		boolean [] matches = new boolean [files.length];
		int num_matches = 0;
		Pattern filename_pattern= Pattern.compile(regex);
		int latest=-1;
		LocalDateTime [] dts = new LocalDateTime[files.length];
		for (int i = 0; i < files.length; i++) if (files[i].isFile()){
			long fileLastModifiedDate = files[i].lastModified();
			dts[i] = Instant.ofEpochMilli(fileLastModifiedDate).atZone(ZoneId.systemDefault()).toLocalDateTime();
			if ((start_date != null) && dts[i].isBefore(start_date)){
				continue; // too early
			}
			if ((end_date != null) && dts[i].isAfter(end_date)){
				continue; // too late
			}
			if (!filename_pattern.matcher(files[i].getName()).matches()) {
				continue; // does not match
			}
			matches[i] = true;
			num_matches++;
			if ((latest < 0) || dts[i].isAfter(dts[latest])) {
				latest = i;
			}
		}
		if (num_matches >1) {
			System.out.println("dir="+model_dir+", num_matches="+num_matches);
		}
		if (latest >= 0) {
			//Prefs.getFileSeparator()
			return model_path+Prefs.getFileSeparator()+files[latest].getName();
		}
		// find latest
		return null;
	}
	
	public static String [] removeDuplicatesSort(String [] paths) {
		HashMap<String,String> scene_files = new HashMap<String,String>();
		DateTimeFormatter formatter = DateTimeFormatter.ofPattern("MM/dd/yyyy HH:mm:ss.SS zzz");// may be VV instead of zzz
		for (int i = 0; i < paths.length; i++) {
			
			String sts = OrthoMap.getNameFromPath(paths[i]);
			String model_dir =  OrthoMap.getModelPathFromPath(paths[i]);
			if (scene_files.containsKey(sts)) {
				String path_old = scene_files.get(sts);
				long old_date = (new File(path_old)).lastModified();
				long new_date = (new File(paths[i])).lastModified();
				boolean replace = new_date > old_date; 
				LocalDateTime old_dt=Instant.ofEpochMilli(old_date).atZone(ZoneId.systemDefault()).toLocalDateTime();
				LocalDateTime new_dt=Instant.ofEpochMilli(new_date).atZone(ZoneId.systemDefault()).toLocalDateTime();
				System.out.println("Duplicate scene found: "+sts+" in two files:");
				System.out.println("1: "+path_old+" @ "+old_dt.atZone(ZoneId.systemDefault()).format(formatter));
				System.out.println("2: "+paths[i]+" @ "+new_dt.atZone(ZoneId.systemDefault()).format(formatter));
				System.out.println("Using "+(replace ? 2 : 1) +" as it is not older");
				if (replace) {
					scene_files.put(sts, paths[i]);
				}
			} else {
				scene_files.put(sts, paths[i]);
			}
		}
		// assuming string ts have the same order as double timestamps
		String [] filtered_ts = scene_files.keySet().toArray(new String[0]);
		Arrays.sort(filtered_ts);
		String [] filtered_paths = new String [filtered_ts.length];
		for (int i = 0; i < filtered_paths.length; i++) {
			filtered_paths[i] = scene_files.get(filtered_ts[i]);
		}
		return filtered_paths;
	}
	
	
	
}
