/*
       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.
 */
package org.apache.cordova.file;

import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.os.Build;
import android.os.Environment;
import android.util.Base64;

import org.apache.cordova.CordovaPreferences;
import org.apache.cordova.CordovaResourceApi;
import org.json.JSONException;
import org.json.JSONObject;

import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.nio.channels.FileChannel;
import java.nio.charset.Charset;

public class LocalFilesystem extends Filesystem {
    private final Context context;

    public LocalFilesystem(String name, Context context, CordovaResourceApi resourceApi, File fsRoot, CordovaPreferences preferences) {
        super(Uri.fromFile(fsRoot).buildUpon().appendEncodedPath("").build(), name, resourceApi, preferences);
        this.context = context;
    }

    public String filesystemPathForFullPath(String fullPath) {
        return new File(rootUri.getPath(), fullPath).toString();
    }

    @Override
    public String filesystemPathForURL(LocalFilesystemURL url) {
        return filesystemPathForFullPath(url.path);
    }

    private String fullPathForFilesystemPath(String absolutePath) {
        if (absolutePath != null && absolutePath.startsWith(rootUri.getPath())) {
            return absolutePath.substring(rootUri.getPath().length() - 1);
        }
        return null;
    }

    @Override
    public Uri toNativeUri(LocalFilesystemURL inputURL) {
        return nativeUriForFullPath(inputURL.path);
    }

    @Override
    public LocalFilesystemURL toLocalUri(Uri inputURL) {
        if (!"file".equals(inputURL.getScheme())) {
            return null;
        }
        File f = new File(inputURL.getPath());
        // Removes and duplicate /s (e.g. file:///a//b/c)
        Uri resolvedUri = Uri.fromFile(f);
        String rootUriNoTrailingSlash = rootUri.getEncodedPath();
        rootUriNoTrailingSlash = rootUriNoTrailingSlash.substring(0, rootUriNoTrailingSlash.length() - 1);
        if (!resolvedUri.getEncodedPath().startsWith(rootUriNoTrailingSlash)) {
            return null;
        }
        String subPath = resolvedUri.getEncodedPath().substring(rootUriNoTrailingSlash.length());
        // Strip leading slash
        if (!subPath.isEmpty()) {
            subPath = subPath.substring(1);
        }

        Uri.Builder b = createLocalUriBuilder();

        if (!subPath.isEmpty()) {
            b.appendEncodedPath(subPath);
        }
        if (f.isDirectory()) {
            // Add trailing / for directories.
            b.appendEncodedPath("");
        }
        return LocalFilesystemURL.parse(b.build());
    }

    @Override
    public LocalFilesystemURL URLforFilesystemPath(String path) {
        return localUrlforFullPath(fullPathForFilesystemPath(path));
    }

    @Override
    public JSONObject getFileForLocalURL(LocalFilesystemURL inputURL,
            String path, JSONObject options, boolean directory) throws FileExistsException, IOException, TypeMismatchException, EncodingException, JSONException {
        boolean create = false;
        boolean exclusive = false;

        if (options != null) {
            create = options.optBoolean("create");
            if (create) {
                exclusive = options.optBoolean("exclusive");
            }
        }

        // Check for a ":" character in the file to line up with BB and iOS
        if (path.contains(":")) {
            throw new EncodingException("This path has an invalid \":\" in it.");
        }

        LocalFilesystemURL requestedURL;

        // Check whether the supplied path is absolute or relative
        if (directory && !path.endsWith("/")) {
            path += "/";
        }
        if (path.startsWith("/")) {
            requestedURL = localUrlforFullPath(normalizePath(path));
        } else {
            requestedURL = localUrlforFullPath(normalizePath(inputURL.path + "/" + path));
        }

        File fp = new File(this.filesystemPathForURL(requestedURL));

        if (create) {
            if (exclusive && fp.exists()) {
                throw new FileExistsException("create/exclusive fails");
            }
            if (directory) {
                fp.mkdir();
            } else {
                fp.createNewFile();
            }
            if (!fp.exists()) {
                throw new FileExistsException("create fails");
            }
        }
        else {
            if (!fp.exists()) {
                throw new FileNotFoundException("path does not exist");
            }
            if (directory) {
                if (fp.isFile()) {
                    throw new TypeMismatchException("path doesn't exist or is file");
                }
            } else {
                if (fp.isDirectory()) {
                    throw new TypeMismatchException("path doesn't exist or is directory");
                }
            }
        }

        // Return the directory
        return makeEntryForURL(requestedURL);
    }

    @Override
    public boolean removeFileAtLocalURL(LocalFilesystemURL inputURL) throws InvalidModificationException {

        File fp = new File(filesystemPathForURL(inputURL));

        // You can't delete a directory that is not empty
        if (fp.isDirectory() && fp.list().length > 0) {
            throw new InvalidModificationException("You can't delete a directory that is not empty.");
        }

        return fp.delete();
    }

    @Override
    public boolean exists(LocalFilesystemURL inputURL) {
        File fp = new File(filesystemPathForURL(inputURL));
        return fp.exists();
    }

    @Override
    public long getFreeSpaceInBytes() {
        return DirectoryManager.getFreeSpaceInBytes(rootUri.getPath());
    }

    @Override
    public boolean recursiveRemoveFileAtLocalURL(LocalFilesystemURL inputURL) throws FileExistsException {
        File directory = new File(filesystemPathForURL(inputURL));
        return removeDirRecursively(directory);
    }

    protected boolean removeDirRecursively(File directory) throws FileExistsException {
        if (directory.isDirectory()) {
            for (File file : directory.listFiles()) {
                removeDirRecursively(file);
            }
        }

        if (!directory.delete()) {
            throw new FileExistsException("could not delete: " + directory.getName());
        } else {
            return true;
        }
    }

    @Override
    public LocalFilesystemURL[] listChildren(LocalFilesystemURL inputURL) throws FileNotFoundException {
        File fp = new File(filesystemPathForURL(inputURL));

        if (!fp.exists()) {
            // The directory we are listing doesn't exist so we should fail.
            throw new FileNotFoundException();
        }

        File[] files = fp.listFiles();
        if (files == null) {
            // inputURL is a directory
            return null;
        }
        LocalFilesystemURL[] entries = new LocalFilesystemURL[files.length];
        for (int i = 0; i < files.length; i++) {
            entries[i] = URLforFilesystemPath(files[i].getPath());
        }

        return entries;
    }

    @Override
    public JSONObject getFileMetadataForLocalURL(LocalFilesystemURL inputURL) throws FileNotFoundException {
        File file = new File(filesystemPathForURL(inputURL));

        if (!file.exists()) {
            throw new FileNotFoundException("File at " + inputURL.uri + " does not exist.");
        }

        JSONObject metadata = new JSONObject();
        try {
            // Ensure that directories report a size of 0
            metadata.put("size", file.isDirectory() ? 0 : file.length());
            metadata.put("type", resourceApi.getMimeType(Uri.fromFile(file)));
            metadata.put("name", file.getName());
            metadata.put("fullPath", inputURL.path);
            metadata.put("lastModifiedDate", file.lastModified());
        } catch (JSONException e) {
            return null;
        }
        return metadata;
    }

    private void copyFile(Filesystem srcFs, LocalFilesystemURL srcURL, File destFile, boolean move) throws IOException, InvalidModificationException, NoModificationAllowedException {
        if (move) {
            String realSrcPath = srcFs.filesystemPathForURL(srcURL);
            if (realSrcPath != null) {
                File srcFile = new File(realSrcPath);
                if (srcFile.renameTo(destFile)) {
                    return;
                }
                // Trying to rename the file failed.  Possibly because we moved across file system on the device.
            }
        }

        CordovaResourceApi.OpenForReadResult offr = resourceApi.openForRead(srcFs.toNativeUri(srcURL));
        resourceApi.copyResource(offr, new FileOutputStream(destFile));

        if (move) {
            srcFs.removeFileAtLocalURL(srcURL);
        }
    }

    private void copyDirectory(Filesystem srcFs, LocalFilesystemURL srcURL, File dstDir, boolean move) throws IOException, NoModificationAllowedException, InvalidModificationException, FileExistsException {
        if (move) {
            String realSrcPath = srcFs.filesystemPathForURL(srcURL);
            if (realSrcPath != null) {
                File srcDir = new File(realSrcPath);
                // If the destination directory already exists and is empty then delete it.  This is according to spec.
                if (dstDir.exists()) {
                    if (dstDir.list().length > 0) {
                        throw new InvalidModificationException("directory is not empty");
                    }
                    dstDir.delete();
                }
                // Try to rename the directory
                if (srcDir.renameTo(dstDir)) {
                    return;
                }
                // Trying to rename the file failed.  Possibly because we moved across file system on the device.
            }
        }

        if (dstDir.exists()) {
            if (dstDir.list().length > 0) {
                throw new InvalidModificationException("directory is not empty");
            }
        } else {
            if (!dstDir.mkdir()) {
                // If we can't create the directory then fail
                throw new NoModificationAllowedException("Couldn't create the destination directory");
            }
        }

        LocalFilesystemURL[] children = srcFs.listChildren(srcURL);
        for (LocalFilesystemURL childLocalUrl : children) {
            File target = new File(dstDir, new File(childLocalUrl.path).getName());
            if (childLocalUrl.isDirectory) {
                copyDirectory(srcFs, childLocalUrl, target, false);
            } else {
                copyFile(srcFs, childLocalUrl, target, false);
            }
        }

        if (move) {
            srcFs.recursiveRemoveFileAtLocalURL(srcURL);
        }
    }

    @Override
    public JSONObject copyFileToURL(LocalFilesystemURL destURL, String newName,
            Filesystem srcFs, LocalFilesystemURL srcURL, boolean move) throws IOException, InvalidModificationException, JSONException, NoModificationAllowedException, FileExistsException {

        // Check to see if the destination directory exists
        String newParent = this.filesystemPathForURL(destURL);
        File destinationDir = new File(newParent);
        if (!destinationDir.exists()) {
            // The destination does not exist so we should fail.
            throw new FileNotFoundException("The source does not exist");
        }

        // Figure out where we should be copying to
        final LocalFilesystemURL destinationURL = makeDestinationURL(newName, srcURL, destURL, srcURL.isDirectory);

        Uri dstNativeUri = toNativeUri(destinationURL);
        Uri srcNativeUri = srcFs.toNativeUri(srcURL);
        // Check to see if source and destination are the same file
        if (dstNativeUri.equals(srcNativeUri)) {
            throw new InvalidModificationException("Can't copy onto itself");
        }

        if (move && !srcFs.canRemoveFileAtLocalURL(srcURL)) {
            throw new InvalidModificationException("Source URL is read-only (cannot move)");
        }

        File destFile = new File(dstNativeUri.getPath());
        if (destFile.exists()) {
            if (!srcURL.isDirectory && destFile.isDirectory()) {
                throw new InvalidModificationException("Can't copy/move a file to an existing directory");
            } else if (srcURL.isDirectory && destFile.isFile()) {
                throw new InvalidModificationException("Can't copy/move a directory to an existing file");
            }
        }

        if (srcURL.isDirectory) {
            // E.g. Copy /sdcard/myDir to /sdcard/myDir/backup
            if (dstNativeUri.toString().startsWith(srcNativeUri.toString() + '/')) {
                throw new InvalidModificationException("Can't copy directory into itself");
            }
            copyDirectory(srcFs, srcURL, destFile, move);
        } else {
            copyFile(srcFs, srcURL, destFile, move);
        }
        return makeEntryForURL(destinationURL);
    }

    @Override
    public long writeToFileAtURL(LocalFilesystemURL inputURL, String data,
            int offset, boolean isBinary) throws IOException, NoModificationAllowedException {

        boolean append = false;
        if (offset > 0) {
            this.truncateFileAtURL(inputURL, offset);
            append = true;
        }

        byte[] rawData;
        if (isBinary) {
            rawData = Base64.decode(data, Base64.DEFAULT);
        } else {
            rawData = data.getBytes(Charset.defaultCharset());
        }
        ByteArrayInputStream in = new ByteArrayInputStream(rawData);
        try
        {
            byte buff[] = new byte[rawData.length];
            String absolutePath = filesystemPathForURL(inputURL);
            FileOutputStream out = new FileOutputStream(absolutePath, append);
            try {
                in.read(buff, 0, buff.length);
                out.write(buff, 0, rawData.length);
                out.flush();
            } finally {
                // Always close the output
                out.close();
            }
            if (isPublicDirectory(absolutePath)) {
                broadcastNewFile(Uri.fromFile(new File(absolutePath)));
            }
        }
        catch (NullPointerException e)
        {
            // This is a bug in the Android implementation of the Java Stack
            NoModificationAllowedException realException = new NoModificationAllowedException(inputURL.toString());
            realException.initCause(e);
            throw realException;
        }

        return rawData.length;
    }

    private boolean isPublicDirectory(String absolutePath) {
        // TODO: should expose a way to scan app's private files (maybe via a flag).
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            // Lollipop has a bug where SD cards are null.
            for (File f : context.getExternalMediaDirs()) {
                if(f != null && absolutePath.startsWith(f.getAbsolutePath())) {
                    return true;
                }
            }
        }

        String extPath = Environment.getExternalStorageDirectory().getAbsolutePath();
        return absolutePath.startsWith(extPath);
    }

     /**
     * Send broadcast of new file so files appear over MTP
     */
    private void broadcastNewFile(Uri nativeUri) {
        Intent intent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, nativeUri);
        context.sendBroadcast(intent);
    }

    @Override
    public long truncateFileAtURL(LocalFilesystemURL inputURL, long size) throws IOException {
        File file = new File(filesystemPathForURL(inputURL));

        if (!file.exists()) {
            throw new FileNotFoundException("File at " + inputURL.uri + " does not exist.");
        }

        RandomAccessFile raf = new RandomAccessFile(filesystemPathForURL(inputURL), "rw");
        try {
            if (raf.length() >= size) {
                FileChannel channel = raf.getChannel();
                channel.truncate(size);
                return size;
            }

            return raf.length();
        } finally {
            raf.close();
        }


    }

    @Override
    public boolean canRemoveFileAtLocalURL(LocalFilesystemURL inputURL) {
        String path = filesystemPathForURL(inputURL);
        File file = new File(path);
        return file.exists();
    }
}
