/*
 *  Licensed to the Apache Software Foundation (ASF) under one or more
 *  contributor license agreements.  See the NOTICE file distributed with
 *  this work for additional information regarding copyright ownership.
 *  The ASF licenses this file to You 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.
 */

#include "AndroidSystemNatives.h"
#include "JNIHelp.h"
#include "LocalArray.h"
#include "ScopedByteArray.h"
#include "ScopedFd.h"

#include <string.h>
#include <fcntl.h>
#include <time.h>
#include <utime.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <dirent.h>
#include <errno.h>

// BEGIN android-note: this file has been extensively rewritten to
// remove fixed-length buffers, buffer overruns, duplication, and
// poor choices of where to divide the work between Java and native
// code.

static jbyteArray java_io_File_getCanonImpl(JNIEnv* env, jobject, jbyteArray pathBytes) {
    ScopedByteArray path(env, pathBytes);
    // The only thing this native code currently does is truncate the byte[] at
    // the first NUL.
    // TODO: this is completely pointless. we should do this in Java, or do all of getCanonicalPath in native code. (realpath(2)?)
    size_t length = strlen(&path[0]);
    jbyteArray result = env->NewByteArray(length);
    env->SetByteArrayRegion(result, 0, length, path.bytes());
    return result;
}

static jboolean java_io_File_deleteImpl(JNIEnv* env, jobject, jbyteArray pathBytes) {
    ScopedByteArray path(env, pathBytes);
    return (remove(&path[0]) == 0);
}

static bool doStat(JNIEnv* env, jbyteArray pathBytes, struct stat& sb) {
    ScopedByteArray path(env, pathBytes);
    return (stat(&path[0], &sb) == 0);
}

static jlong java_io_File_lengthImpl(JNIEnv* env, jobject, jbyteArray pathBytes) {
    struct stat sb;
    if (!doStat(env, pathBytes, sb)) {
        // We must return 0 for files that don't exist.
        // TODO: shouldn't we throw an IOException for ELOOP or EACCES?
        return 0;
    }
    
    /*
     * This android-changed code explicitly treats non-regular files (e.g.,
     * sockets and block-special devices) as having size zero. Some synthetic
     * "regular" files may report an arbitrary non-zero size, but
     * in these cases they generally report a block count of zero.
     * So, use a zero block count to trump any other concept of
     * size.
     * 
     * TODO: why do we do this?
     */
    if (!S_ISREG(sb.st_mode) || sb.st_blocks == 0) {
        return 0;
    }
    return sb.st_size;
}

static jlong java_io_File_lastModifiedImpl(JNIEnv* env, jobject, jbyteArray pathBytes) {
    struct stat sb;
    if (!doStat(env, pathBytes, sb)) {
        return 0;
    }
    return static_cast<jlong>(sb.st_mtime) * 1000L;
}

static jboolean java_io_File_isDirectoryImpl(JNIEnv* env, jobject, jbyteArray pathBytes) {
    struct stat sb;
    return (doStat(env, pathBytes, sb) && S_ISDIR(sb.st_mode));
}

static jboolean java_io_File_isFileImpl(JNIEnv* env, jobject, jbyteArray pathBytes) {
    struct stat sb;
    return (doStat(env, pathBytes, sb) && S_ISREG(sb.st_mode));
}

static jboolean java_io_File_existsImpl(JNIEnv* env, jobject, jbyteArray pathBytes) {
    ScopedByteArray path(env, pathBytes);
    return (access(&path[0], F_OK) == 0);
}

static jboolean java_io_File_isReadableImpl(JNIEnv* env, jobject, jbyteArray pathBytes) {
    ScopedByteArray path(env, pathBytes);
    return (access(&path[0], R_OK) == 0);
}

static jboolean java_io_File_isWritableImpl(JNIEnv* env, jobject recv, jbyteArray pathBytes) {
    ScopedByteArray path(env, pathBytes);
    return (access(&path[0], W_OK) == 0);
}

static jbyteArray java_io_File_getLinkImpl(JNIEnv* env, jobject, jbyteArray pathBytes) {
    ScopedByteArray path(env, pathBytes);

    // We can't know how big a buffer readlink(2) will need, so we need to
    // loop until it says "that fit".
    size_t bufSize = 512;
    while (true) {
        LocalArray<512> buf(bufSize);
        ssize_t len = readlink(&path[0], &buf[0], buf.size() - 1);
        if (len == -1) {
            // An error occurred.
            return pathBytes;
        }
        if (static_cast<size_t>(len) < buf.size() - 1) {
            // The buffer was big enough.
            // TODO: why do we bother with the NUL termination? (if you change this, remove the "- 1"s above.)
            buf[len] = '\0'; // readlink(2) doesn't NUL-terminate.
            jbyteArray result = env->NewByteArray(len);
            const jbyte* src = reinterpret_cast<const jbyte*>(&buf[0]);
            env->SetByteArrayRegion(result, 0, len, src);
            return result;
        }
        // Try again with a bigger buffer.
        bufSize *= 2;
    }
}

static jboolean java_io_File_setLastModifiedImpl(JNIEnv* env, jobject, jbyteArray pathBytes, jlong ms) {
    ScopedByteArray path(env, pathBytes);
    
    // We want to preserve the access time.
    struct stat sb;
    if (stat(&path[0], &sb) == -1) {
        return JNI_FALSE;
    }
    
    // TODO: we could get microsecond resolution with utimes(3), "legacy" though it is.
    utimbuf times;
    times.actime = sb.st_atime;
    times.modtime = static_cast<time_t>(ms / 1000);
    return (utime(&path[0], &times) == 0);
}

static jboolean java_io_File_setReadOnlyImpl(JNIEnv* env, jobject recv, jbyteArray pathBytes) {
    ScopedByteArray path(env, pathBytes);

    struct stat sb;
    if (stat(&path[0], &sb) == -1) {
        return JNI_FALSE;
    }

    // Strictly, this is set-not-writable (i.e. we leave the execute
    // bits untouched), but that's deliberate.
    return (chmod(&path[0], sb.st_mode & ~0222) == 0);
}

// Iterates over the filenames in the given directory.
class ScopedReaddir {
public:
    ScopedReaddir(const char* path) {
        mDirStream = opendir(path);
        mIsBad = (mDirStream == NULL);
    }

    ~ScopedReaddir() {
        if (mDirStream != NULL) {
            closedir(mDirStream);
        }
    }

    // Returns the next filename, or NULL.
    const char* next() {
        dirent* result = NULL;
        int rc = readdir_r(mDirStream, &mEntry, &result);
        if (rc != 0) {
            mIsBad = true;
            return NULL;
        }
        return (result != NULL) ? result->d_name : NULL;
    }

    // Has an error occurred on this stream?
    bool isBad() const {
        return mIsBad;
    }

private:
    DIR* mDirStream;
    dirent mEntry;
    bool mIsBad;
};

// DirEntry and DirEntries is a minimal equivalent of std::forward_list
// for the filenames.
struct DirEntry {
    DirEntry(const char* filename) : name(strlen(filename)) {
        strcpy(&name[0], filename);
        next = NULL;
    }
    // On Linux, the ext family all limit the length of a directory entry to
    // less than 256 characters.
    LocalArray<256> name;
    DirEntry* next;
};

class DirEntries {
public:
    DirEntries() : mSize(0), mHead(NULL) {
    }

    ~DirEntries() {
        while (mHead) {
            pop_front();
        }
    }

    bool push_front(const char* name) {
        DirEntry* oldHead = mHead;
        mHead = new DirEntry(name);
        if (mHead == NULL) {
            return false;
        }
        mHead->next = oldHead;
        ++mSize;
        return true;
    }

    const char* front() const {
        return &mHead->name[0];
    }

    void pop_front() {
        DirEntry* popped = mHead;
        if (popped != NULL) {
            mHead = popped->next;
            --mSize;
            delete popped;
        }
    }

    size_t size() const {
        return mSize;
    }

private:
    size_t mSize;
    DirEntry* mHead;
};

// Reads the directory referred to by 'pathBytes', adding each directory entry
// to 'entries'.
static bool readDirectory(JNIEnv* env, jbyteArray pathBytes, DirEntries& entries) {
    ScopedByteArray path(env, pathBytes);
    ScopedReaddir dir(&path[0]);
    if (dir.isBad()) {
        return false;
    }
    const char* filename;
    while ((filename = dir.next()) != NULL) {
        if (strcmp(filename, ".") != 0 && strcmp(filename, "..") != 0) {
            if (!entries.push_front(filename)) {
                jniThrowException(env, "java/lang/OutOfMemoryError", NULL);
                return false;
            }
        }
    }
    return true;
}

static jobjectArray java_io_File_listImpl(JNIEnv* env, jobject, jbyteArray pathBytes) {
    // Read the directory entries into an intermediate form.
    DirEntries files;
    if (!readDirectory(env, pathBytes, files)) {
        return NULL;
    }
    // Translate the intermediate form into a Java String[].
    jclass stringClass = env->FindClass("java/lang/String");
    if (stringClass == NULL) {
        return NULL;
    }
    jobjectArray result = env->NewObjectArray(files.size(), stringClass, NULL);
    for (int i = 0; files.size() != 0; files.pop_front(), ++i) {
        jstring javaFilename = env->NewStringUTF(files.front());
        if (env->ExceptionCheck()) {
            return NULL;
        }
        env->SetObjectArrayElement(result, i, javaFilename);
        if (env->ExceptionCheck()) {
            return NULL;
        }
        env->DeleteLocalRef(javaFilename);
    }
    return result;
}

static jboolean java_io_File_mkdirImpl(JNIEnv* env, jobject, jbyteArray pathBytes) {
    ScopedByteArray path(env, pathBytes);
    // On Android, we don't want default permissions to allow global access.
    return (mkdir(&path[0], S_IRWXU) == 0);
}

static jboolean java_io_File_createNewFileImpl(JNIEnv* env, jobject, jbyteArray pathBytes) {
    ScopedByteArray path(env, pathBytes);
    // On Android, we don't want default permissions to allow global access.
    ScopedFd fd(open(&path[0], O_CREAT | O_EXCL, 0600));
    if (fd.get() != -1) {
        // We created a new file. Success!
        return JNI_TRUE;
    }
    if (errno == EEXIST) {
        // The file already exists.
        return JNI_FALSE;
    }
    jniThrowIOException(env, errno);
    return JNI_FALSE; // Ignored by Java; keeps the C++ compiler happy.
}

static jboolean java_io_File_renameToImpl(JNIEnv* env, jobject, jbyteArray oldPathBytes, jbyteArray newPathBytes) {
    ScopedByteArray oldPath(env, oldPathBytes);
    ScopedByteArray newPath(env, newPathBytes);
    return (rename(&oldPath[0], &newPath[0]) == 0);
}

static JNINativeMethod gMethods[] = {
    /* name, signature, funcPtr */
    { "createNewFileImpl",  "([B)Z",  (void*) java_io_File_createNewFileImpl },
    { "deleteImpl",         "([B)Z",  (void*) java_io_File_deleteImpl },
    { "existsImpl",         "([B)Z",  (void*) java_io_File_existsImpl },
    { "getCanonImpl",       "([B)[B", (void*) java_io_File_getCanonImpl },
    { "getLinkImpl",        "([B)[B", (void*) java_io_File_getLinkImpl },
    { "isDirectoryImpl",    "([B)Z",  (void*) java_io_File_isDirectoryImpl },
    { "isFileImpl",         "([B)Z",  (void*) java_io_File_isFileImpl },
    { "isReadableImpl",     "([B)Z",  (void*) java_io_File_isReadableImpl },
    { "isWritableImpl",     "([B)Z",  (void*) java_io_File_isWritableImpl },
    { "lastModifiedImpl",   "([B)J",  (void*) java_io_File_lastModifiedImpl },
    { "lengthImpl",         "([B)J",  (void*) java_io_File_lengthImpl },
    { "listImpl",           "([B)[Ljava/lang/String;", (void*) java_io_File_listImpl },
    { "mkdirImpl",          "([B)Z",  (void*) java_io_File_mkdirImpl },
    { "renameToImpl",       "([B[B)Z",(void*) java_io_File_renameToImpl },
    { "setLastModifiedImpl","([BJ)Z", (void*) java_io_File_setLastModifiedImpl },
    { "setReadOnlyImpl",    "([B)Z",  (void*) java_io_File_setReadOnlyImpl },
};
int register_java_io_File(JNIEnv* env) {
    return jniRegisterNativeMethods(env, "java/io/File",
            gMethods, NELEM(gMethods));
}
