/*-
 * ~~~~~~licensing~~~~~~
 * base-support
 * ==========
 * Copyright (C) 2020 - 2021 EmDev LLC
 * ==========
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * 
 *      http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 * ~~~~~~/licensing~~~~~~
 */
package ru.entaxy.platform.base.support;

import java.io.File;
import java.io.IOException;
import java.net.MalformedURLException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.Calendar;

import org.apache.commons.codec.digest.DigestUtils;

public class FileUtils {

	public static class FileHelper {
	
		protected File file = null;

		protected String fileMd5Hash = "";
		
		protected String md5FilePath = "";
		protected String currentMd5 = null;
		
		protected String timestampFilePath = "";
		protected String currentTimestamp = null;
		
		public FileHelper(String filePath) {
			this(new File(filePath));
		}
		
		public FileHelper(File file) {
			this.file = file;
			this.md5FilePath = file.getAbsolutePath().concat(".md5");
			this.timestampFilePath = file.getAbsolutePath().concat(".timestamp");
		}
		
		public boolean isReadable() {
			return file.exists() && file.canRead(); 
		}

		protected String calcMd5() {
			if (!CommonUtils.isValid(this.fileMd5Hash))
				try {
					this.fileMd5Hash = DigestUtils.md5Hex(this.file.toURI().toURL().openStream());
				} catch (MalformedURLException e) {
					e.printStackTrace();
				} catch (IOException e) {
					e.printStackTrace();
				}
			return this.fileMd5Hash; 
		}
		
		protected String readMd5() {
			if (this.currentMd5 == null)
			try {
				this.currentMd5 = Files.readString((new File(this.md5FilePath)).toPath());
			} catch (IOException e) {
				this.currentMd5 = ""; 
			}
			return this.currentMd5;
		}
		
		public boolean isChanged() {
			return !CommonUtils.isValid(this.readMd5()) || !this.readMd5().equals(this.calcMd5());
		}

		public String getTimestamp() {
			if (this.currentTimestamp == null)
				try {
					this.currentTimestamp = Files.readString((new File(this.timestampFilePath)).toPath());
				} catch (IOException e) {
					this.currentTimestamp = ""; 
				}
			return this.currentTimestamp;
		}
		
		public String getMd5() {
			this.fileMd5Hash = "";
			return calcMd5();
		}
		
		public File getFile() {
			return file;
		}

		public String getFileMd5Hash() {
			return calcMd5();
		}

		public String updateMd5() {
			String result = getMd5();
			if (CommonUtils.isValid(result))
				try {
					FileUtils.string2file(result, md5FilePath);
					result = readMd5();
				} catch (IOException e) {
					result = null;
				}
			return result;
		}
		
		public String updateTimestamp() {
			String timestamp = Calendar.getInstance().getTimeInMillis() + "";
			String result = "";
			try {
				FileUtils.string2file(timestamp, timestampFilePath);
				this.currentTimestamp = null;
				result = getTimestamp();
			} catch (IOException e) {
				result = null;
			}
			return result;
		}
		
	}
	
	public static void string2file(String content, String filePath) throws IOException {
		string2file(content, new File(filePath));
	}
	
	public static void string2file(String content, File file) throws IOException {
		if (!file.exists())
			file.createNewFile();
		Files.writeString(file.toPath(), content);
	}
	
}
