/*
 *   Copyright 2013 Brian Rosenberger (Brutex Network)
 *
 *   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.
 */

package net.brutex.xservices.types;

import java.io.File;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URI;
import java.net.URLEncoder;
import java.nio.file.FileSystems;
import java.nio.file.Files;
import java.nio.file.LinkOption;
import java.nio.file.Path;
import java.nio.file.attribute.BasicFileAttributeView;
import java.nio.file.attribute.BasicFileAttributes;
import java.nio.file.attribute.DosFileAttributeView;
import java.nio.file.attribute.DosFileAttributes;
import java.nio.file.attribute.FileTime;
import java.nio.file.attribute.PosixFileAttributeView;
import java.nio.file.attribute.PosixFileAttributes;
import java.nio.file.attribute.UserPrincipal;
import java.util.GregorianCalendar;

import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorOrder;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlType;
/**
 * @author Brian Rosenberger, bru(at)brutex.de
 *
 */



@XmlRootElement
@XmlType(propOrder={"name", "path", "filesize", "owner", "lastModifiedDate", "createdDate", "lastAccessDate", "mimeType", 
					"readonly", "hidden", "directory", "symbolicLink", "archive", "system", "downloadUrl"})
@XmlAccessorType(XmlAccessType.PROPERTY)
public class FileInfoType
{
  private String name;
  private String path;
  private long filesize;
  private boolean isReadonly;
  private boolean isHidden;
  private boolean isDirectory;
  private boolean isSymbolicLink;
  private boolean isArchive;
  private boolean isSystem;
  private GregorianCalendar lastModifiedDate;
  private GregorianCalendar createdDate;
  private GregorianCalendar lastAccessDate;
  private String owner;
  private String mimeType;
  private URI downloadUrl;
  

  public FileInfoType()
  {
  }
  
  public FileInfoType(Path p) throws IOException {
	  	this.name = p.getFileName().toString();
	    this.path = p.toAbsolutePath().toString().replace('\\', '/');

	  
		BasicFileAttributeView basicView = Files.getFileAttributeView(p, BasicFileAttributeView.class);
		BasicFileAttributes basic;
		basic = basicView.readAttributes();
		
		this.isDirectory = basic.isDirectory();
		this.isSymbolicLink = basic.isSymbolicLink();
		this.filesize = basic.size();
		this.lastModifiedDate = (GregorianCalendar) GregorianCalendar.getInstance();
		this.lastModifiedDate.setTimeInMillis(basic.lastModifiedTime().toMillis());
		this.createdDate = (GregorianCalendar) GregorianCalendar.getInstance();
		this.createdDate.setTimeInMillis(basic.creationTime().toMillis());
		this.lastAccessDate = (GregorianCalendar) GregorianCalendar.getInstance();
		this.lastAccessDate.setTimeInMillis(basic.lastAccessTime().toMillis());
		
		// Try to set the Mime Type for that file
		// or default to octet-stream
		if(!isDirectory) {
			this.mimeType = Files.probeContentType(p);
			if(this.mimeType==null) mimeType = "application/octet-stream";
		} else {
			this.mimeType = null;
		}
		
		// Set the file/ directory owner
		this.owner = Files.getOwner(p).getName();
		
		//Dos specific Attributes
		DosFileAttributeView dosView = Files.getFileAttributeView(p, DosFileAttributeView.class);
		if(dosView != null) {
			DosFileAttributes dos = dosView.readAttributes();
			this.isReadonly = dos.isReadOnly();
			this.isHidden = dos.isHidden();
			this.isArchive = dos.isArchive();
			this.isSystem = dos.isSystem();
		}
		
		//POSIX specific Attributes
		PosixFileAttributeView posixView = Files.getFileAttributeView(p, PosixFileAttributeView.class);
		if(posixView != null) {
			PosixFileAttributes posix = posixView.readAttributes();
			//TODO: Unix specific file attributes
		}
		
  }

  
  public FileInfoType(Path file, URI downloadURL) throws IOException {
	  this(file);
	  try {
		this.downloadUrl = URI.create(downloadURL+URLEncoder.encode(this.path, "UTF-8"));
	} catch (UnsupportedEncodingException e) {
		// TODO Auto-generated catch block
		e.printStackTrace();
	}
  }

/**
 * @return the name
 */
  @XmlElement(name="name")
public String getName() {
	return name;
}

/**
 * @return the path
 */
	@XmlElement(name = "path")
public String getPath() {
	return path;
}

/**
 * @return the filesize
 */
@XmlElement(name="filesize")
public long getFilesize() {
	return filesize;
}

/**
 * @return the isReadonly
 */
@XmlElement(name="isReadonly")
public boolean isReadonly() {
	return isReadonly;
}

/**
 * @return the isHidden
 */
@XmlElement(name="isHidden")
public boolean isHidden() {
	return isHidden;
}

/**
 * @return the isDirectory
 */
@XmlElement(name="isDirectory")
public boolean isDirectory() {
	return isDirectory;
}

/**
 * @return the isSymbolicLink
 */
@XmlElement(name="isSymbolicLink")
public boolean isSymbolicLink() {
	return isSymbolicLink;
}

/**
 * @return the isArchive
 */
@XmlElement(name="isArchive")
public boolean isArchive() {
	return isArchive;
}

/**
 * @return the isSystem
 */
@XmlElement(name="isSystem")
public boolean isSystem() {
	return isSystem;
}

/**
 * @return the lastModifiedDate
 */
@XmlElement(name="lastModifiedDate")
public GregorianCalendar getLastModifiedDate() {
	return lastModifiedDate;
}

/**
 * @return the createdDate
 */
@XmlElement(name="createdDate")
public GregorianCalendar getCreatedDate() {
	return createdDate;
}

/**
 * @return the lastAccessDate
 */
@XmlElement(name="lastAccessDate")
public GregorianCalendar getLastAccessDate() {
	return lastAccessDate;
}

/**
 * @return the owner
 */
@XmlElement(name="owner")
public String getOwner() {
	return owner;
}

/**
 * @return the mimeType
 */
@XmlElement(name="mimeType")
public String getMimeType() {
	return mimeType;
}

/**
 * @return the downloadUrl
 */
@XmlElement(name="downloadUrl")
public URI getDownloadUrl() {
	return downloadUrl;
}
  
  
}