package org.gnode.nix;

import org.bytedeco.javacpp.IntPointer;
import org.bytedeco.javacpp.Loader;
import org.bytedeco.javacpp.Pointer;
import org.bytedeco.javacpp.annotation.*;
import org.gnode.nix.internal.Utils;

import java.util.ArrayList;

@Platform(value = "linux",
        include = {"<nix/File.hpp>"},
        link = {"nix"},
        linkpath = {"/usr/local/lib/"},
        includepath = {"/usr/local/include/"})
@Namespace("nix")
public class File extends Pointer {

    static {
        Loader.load();
    }

    //--------------------------------------------------
    // Constructors
    //--------------------------------------------------

    /**
     * Constructor that creates an uninitialized File.
     * <p/>
     * Calling any method on an uninitialized file will throw a {@link java.lang.RuntimeException}.
     */
    public File() {
        allocate();
    }

    private native void allocate();

    //--------------------------------------------------
    // Base class methods
    //--------------------------------------------------

    private native
    @Cast("bool")
    boolean isNone();

    /**
     * Checks if file is initialized
     *
     * @return true if initialized else false
     */
    public boolean isInitialized() {
        return !isNone();
    }


    /**
     * Opens a file.
     *
     * @param name The name/path of the file.
     * @param mode The open mode. Check {@link FileMode} for options.
     * @param impl The back-end implementation the should be used to open the file. Check {@link Implementation} for options.
     * @return The opened file.
     * @see FileMode
     * @see Implementation
     */
    public static native
    @ByVal
    File open(@StdString String name, @Cast("nix::FileMode") int mode,
              @Cast("nix::Implementation") int impl);

    /**
     * Opens a file with back-end implementation in hdf5.
     *
     * @param name The name/path of the file.
     * @param mode The open mode. Check {@link FileMode} for options.
     * @return The opened file.
     * @see FileMode
     */
    public static File open(@StdString String name, int mode) {
        return open(name, mode, Implementation.Hdf5);
    }

    /**
     * Opens a file in ReadWrite mode and with back-end implementation in hdf5.
     *
     * @param name The name/path of the file.
     * @return The opened file.
     */
    public static native
    @ByVal
    File open(@StdString String name);

    //------------------------------------------------------
    // Methods for file attribute access.
    //------------------------------------------------------

    private native
    @StdVector
    IntPointer version();

    /**
     * Read the NIX format version from the file.
     * <p/>
     * The version consist of three integers standing for the major, minor and patch version of the nix format.
     *
     * @return The format version of the NIX file.
     */
    public ArrayList<Integer> getVersion() {
        return Utils.convertPointerToList(version());
    }

    /**
     * Read the format hint from the file.
     *
     * @return
     */
    public native
    @Name("format")
    @StdString
    String getFormat();

    /**
     * Return the location / uri.
     *
     * @return The uri string.
     */
    public native
    @Name("location")
    @StdString
    String getLocation();

    /**
     * Get the creation date of the file.
     *
     * @return The creation date of the file.
     */
    public native
    @Cast("time_t")
    long createdAt();

    /**
     * Get the date of the last update.
     *
     * @return The date of the last update.
     */
    public native
    @Cast("time_t")
    long updatedAt();

    /**
     * Sets the time of the last update to the current time if the field is not set.
     */
    public native void setUpdatedAt();

    /**
     * Sets the time of the last update to the current time.
     */
    public native void forceUpdatedAt();

    /**
     * Sets the creation time to the current time if the field is not set.
     */
    public native void setCreatedAt();

    /**
     * Sets the creation time to the provided value even if the attribute is set.
     *
     * @param time The creation time to set.
     */
    public native void forceCreatedAt(@Cast("time_t") long time);


    //------------------------------------------------------
    // Other functions
    //------------------------------------------------------

    /**
     * Close the file.
     */
    public native void close();

    /**
     * Check if the file is currently open.
     *
     * @return True if the file is open, false otherwise.
     */
    public native
    @Cast("bool")
    boolean isOpen();

}

@@ -237,16 +237,39 @@
 rayList;
+%0Aimport java.util.Date;
 %0A%0A@Platf
@@ -3377,32 +3377,94 @@
 getLocation();%0A%0A
+    private native%0A    @Cast(%22time_t%22)%0A    long createdAt();%0A%0A
     /**%0A     * G
@@ -3561,32 +3561,129 @@
   */%0A    public 
+Date getCreatedAt() %7B%0A        return Utils.convertSecondsToDate(createdAt());%0A    %7D%0A%0A    private 
 native%0A    @Cast
@@ -3694,35 +3694,35 @@
 me_t%22)%0A    long 
-cre
+upd
 atedAt();%0A%0A    /
@@ -3838,44 +3838,72 @@
 lic 
-native%0A    @Cast(%22time_t%22)%0A    long 
+Date getUpdatedAt() %7B%0A        return Utils.convertSecondsToDate(
 upda
@@ -3901,33 +3901,40 @@
 Date(updatedAt()
-;
+);%0A    %7D
 %0A%0A    /**%0A     *
@@ -4302,32 +4302,100 @@
 etCreatedAt();%0A%0A
+    private native void forceCreatedAt(@Cast(%22time_t%22) long time);%0A%0A
     /**%0A     * S
@@ -4403,35 +4403,35 @@
 ts the creation 
-tim
+dat
 e to the provide
@@ -4489,19 +4489,19 @@
  @param 
-tim
+dat
 e The cr
@@ -4503,27 +4503,27 @@
 he creation 
-tim
+dat
 e to set.%0A  
@@ -4531,39 +4531,32 @@
   */%0A    public 
-native 
 void forceCreate
@@ -4563,35 +4563,84 @@
 dAt(
-@Cast(%22time_t%22) long time);
+Date date) %7B%0A        forceCreatedAt(Utils.convertDateToSeconds(date));%0A    %7D
 %0A%0A%0A 

update methods