/*
 *  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 "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.

class Path {
public:
    Path(JNIEnv* env, jbyteArray pathBytes)
    : mByteCount(env->GetArrayLength(pathBytes)), mBytes(mByteCount + 1)
    {
        // The Java byte[] doesn't contain a trailing NUL.
        // TODO: the Java byte[] should contain a trailing NUL.
        jbyte* dst = reinterpret_cast<jbyte*>(&mBytes[0]);
        env->GetByteArrayRegion(pathBytes, 0, mByteCount, dst);
        mBytes[mByteCount] = '\0';
        // This is an awful mistake, because '\' is a perfectly acceptable
        // character on Linux/Android. But we've shipped so many versions
        // that behaved like this, I'm too scared to change it.
        // TODO: if we're going to do this, we should do it once, in Java.
        for (char* p = &mBytes[0]; *p; ++p) {
            if (*p == '\\') {
                *p = '/';
            }
        }
    }

    jbyte* bytes() {
        return reinterpret_cast<jbyte*>(&mBytes[0]);
    }

    // Capacity.
    size_t size() const {
        return mByteCount;
    }

    // Element access.
    const char& operator[](size_t n) const { return mBytes[n]; }

private:
    size_t mByteCount;
    LocalArray<512> mBytes;
};


static jbyteArray java_io_File_getCanonImpl(JNIEnv* env, jobject, jbyteArray pathBytes) {
    Path path(env, pathBytes);
    // The only thing this native code currently does is truncate the byte[] at
    // the first NUL, and rewrite '\' as '/'.
    // 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) {
    Path path(env, pathBytes);
    return (remove(&path[0]) == 0);
}

static bool doStat(JNIEnv* env, jbyteArray pathBytes, struct stat& sb) {
    Path 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) {
    Path path(env, pathBytes);
    return (access(&path[0], F_OK) == 0);
}

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

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

static jbyteArray java_io_File_getLinkImpl(JNIEnv* env, jobject, jbyteArray pathBytes) {
    Path 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 (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) {
    Path 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) {
    Path 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);
}

struct ScopedReaddir {
    ScopedReaddir(DIR* dirp) : dirp(dirp) {
    }
    ~ScopedReaddir() {
        if (dirp != NULL) {
            closedir(dirp);
        }
    }
    dirent* next() {
        return readdir(dirp);
    }
    DIR* dirp;
};

// TODO: this is a literal translation of the old code. we should remove the fixed-size buffers here.
#define MaxPath 1024

// TODO: Java doesn't guarantee any specific ordering, and with some file systems you will get results in non-alphabetical order, so I've just done the most convenient thing for the native code, but I wonder if we shouldn't pass down an ArrayList<String> and fill it?
struct LinkedDirEntry {
    static void addFirst(LinkedDirEntry** list, LinkedDirEntry* newEntry) {
        newEntry->next = *list;
        *list = newEntry;
    }

    LinkedDirEntry() : next(NULL) {
    }

    ~LinkedDirEntry() {
        delete next;
    }

    char pathEntry[MaxPath];
    LinkedDirEntry* next;
};

static jobject java_io_File_listImpl(JNIEnv* env, jclass clazz, jbyteArray pathBytes) {
    Path path(env, pathBytes);
    
    ScopedReaddir dir(opendir(&path[0]));
    if (dir.dirp == NULL) {
        // TODO: shouldn't we throw an IOException?
        return NULL;
    }
    
    // TODO: merge this into the loop below.
    dirent* entry = dir.next();
    if (entry == NULL) {
        return NULL;
    }
    char filename[MaxPath];
    strcpy(filename, entry->d_name);

    size_t fileCount = 0;
    LinkedDirEntry* files = NULL;
    while (entry != NULL) {
        if (strcmp(".", filename) != 0 && strcmp("..", filename) != 0) {
            LinkedDirEntry* newEntry = new LinkedDirEntry;
            if (newEntry == NULL) {
                jniThrowException(env, "java/lang/OutOfMemoryError", NULL);
                return NULL;
            }
            strcpy(newEntry->pathEntry, filename);
            
            LinkedDirEntry::addFirst(&files, newEntry);
            ++fileCount;
        }

        entry = dir.next();
        if (entry != NULL) {
            strcpy(filename, entry->d_name);
        }
    }
    
    // TODO: we should kill the ScopedReaddir about here, since we no longer need it.
    
    // TODO: we're supposed to use null to signal errors. we should return "new String[0]" here (or an empty byte[][]).
    if (fileCount == 0) {
        return NULL;
    }
    
    // Create a byte[][].
    // TODO: since the callers all want a String[], why do we return a byte[][]?
    jclass byteArrayClass = env->FindClass("[B");
    if (byteArrayClass == NULL) {
        return NULL;
    }
    jobjectArray answer = env->NewObjectArray(fileCount, byteArrayClass, NULL);
    int arrayIndex = 0;
    for (LinkedDirEntry* file = files; file != NULL; file = file->next) {
        jsize entrylen = strlen(file->pathEntry);
        jbyteArray entrypath = env->NewByteArray(entrylen);
        env->SetByteArrayRegion(entrypath, 0, entrylen, (jbyte *) file->pathEntry);
        env->SetObjectArrayElement(answer, arrayIndex, entrypath);
        env->DeleteLocalRef(entrypath);
        ++arrayIndex;
    }
    return answer;
}

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

static jint java_io_File_newFileImpl(JNIEnv* env, jobject, jbyteArray pathBytes) {
    Path 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 return 0 if we created a new file...
        return 0;
    }
    // ... 1 if the file already existed, and -1 if we failed.
    // TODO: we should return true or false, like our caller,
    // and throw IOException on failure.
    return (errno == EEXIST) ? 1 : -1;
}

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

static JNINativeMethod gMethods[] = {
    /* name, signature, funcPtr */
    { "deleteImpl",         "([B)Z",  (void*) java_io_File_deleteImpl },
    { "existsImpl",         "([B)Z",  (void*) java_io_File_existsImpl },
    { "getCanonImpl",       "([B)[B", (void*) java_io_File_getCanonImpl },
    { "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 },
    { "getLinkImpl",        "([B)[B", (void*) java_io_File_getLinkImpl },
    { "lastModifiedImpl",   "([B)J",  (void*) java_io_File_lastModifiedImpl },
    { "setReadOnlyImpl",    "([B)Z",  (void*) java_io_File_setReadOnlyImpl },
    { "lengthImpl",         "([B)J",  (void*) java_io_File_lengthImpl },
    { "listImpl",           "([B)[[B",(void*) java_io_File_listImpl },
    { "mkdirImpl",          "([B)Z",  (void*) java_io_File_mkdirImpl },
    { "newFileImpl",        "([B)I",  (void*) java_io_File_newFileImpl },
    { "renameToImpl",       "([B[B)Z",(void*) java_io_File_renameToImpl },
    { "setLastModifiedImpl","([BJ)Z", (void*) java_io_File_setLastModifiedImpl },
};
int register_java_io_File(JNIEnv* env) {
    return jniRegisterNativeMethods(env, "java/io/File",
            gMethods, NELEM(gMethods));
}
