//
// JODConverter - Java OpenDocument Converter
// Copyright (C) 2004-2007 - Mirko Nasato <mirko@artofsolving.com>
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.
//
// This library 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
// Lesser General Public License for more details.
// http://www.gnu.org/copyleft/lesser.html
//
package com.artofsolving.jodconverter.test;

import java.io.EOFException;
import java.io.File;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.util.Arrays;

/**
 * Trivially simple file type identifier in the style of *nix file(1) and magic(5)
 * <p>
 * Only intended for checking documents generated by OpenOffice.org by automated tests.
 */
public class FileType {

	public static FileType TXT = new FileType("Plain Text", 0, "");  // fake check; no easy way to detect plain text
	public static FileType PDF = new FileType("PDF", 0, "%PDF-");
	public static FileType SWF = new FileType("Flash", 0, "FWS");
	public static FileType RTF = new FileType("RTF", 0, "{\\rtf");
	public static FileType HTML = new FileType("HTML", 0, "<!DOCTYPE HTML");
	public static FileType XHTML = new FileType("XHTML", 0, "<?xml version=\"1.0\" encoding=\"UTF-8\"?><!DOCTYPE html");
	public static FileType ODT = new FileType("OpenDocument Text", 38, "application/vnd.oasis.opendocument.text");
	public static FileType ODS = new FileType("OpenDocument Spreadsheet", 38, "application/vnd.oasis.opendocument.spreadsheet");
	public static FileType ODP = new FileType("OpenDocument Presentation", 38, "application/vnd.oasis.opendocument.presentation");
	public static FileType SXW = new FileType("OpenOffice.org 1.0 Text", 38, "application/vnd.sun.xml.writer");
	public static FileType SXC = new FileType("OpenOffice.org 1.0 Spreadsheet", 38, "application/vnd.sun.xml.calc");
	public static FileType SXI = new FileType("OpenOffice.org 1.0 Presentation", 38, "application/vnd.sun.xml.impress");
	// no easy way to distinguish between Word, Excel and PowerPoint
	public static FileType MSOFFICE = new FileType("Microsoft Office", 0, new byte[] { (byte) 0320, (byte) 0317, (byte) 0021 });

	private final String name;
	private final long offset;
	private final byte[] magicData;
	
	private FileType(String name, long offset, String magicData) {
		this(name, offset, magicData.getBytes());
	}

	private FileType(String name, long offset, byte[] magicData) {
		this.name = name;
		this.offset = offset;
		this.magicData = magicData;
	}

	public String getName() {
		return name;
	}

	public boolean matches(File file) throws IOException {
		boolean result;
		RandomAccessFile randomAccessFile = new RandomAccessFile(file, "r");
		try {
			result = matches(randomAccessFile);
		} finally {
			randomAccessFile.close();
		}
		return result;
	}

	private boolean matches(RandomAccessFile randomAccessFile) throws IOException {
		randomAccessFile.seek(offset);
		byte[] buffer = new byte[magicData.length];
		try {
			randomAccessFile.readFully(buffer);
			if (Arrays.equals(buffer, magicData)) {
				return true;
			}
		} catch (EOFException eofException) {
			// file too short for the current type
			return false;
		}
		return false;
	}
}