/*
       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.res.AssetManager;
import android.net.Uri;

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

import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.util.HashMap;
import java.util.Map;

public class AssetFilesystem extends Filesystem {

    private final AssetManager assetManager;

    // A custom gradle hook creates the cdvasset.manifest file, which speeds up asset listing a tonne.
    // See: http://stackoverflow.com/questions/16911558/android-assetmanager-list-incredibly-slow
    private static Object listCacheLock = new Object();
    private static boolean listCacheFromFile;
    private static Map<String, String[]> listCache;
    private static Map<String, Long> lengthCache;

    private static final String LOG_TAG = "AssetFilesystem";

    private void lazyInitCaches() {
        synchronized (listCacheLock) {
            if (listCache == null) {
                ObjectInputStream ois = null;
                try {
                    ois = new ObjectInputStream(assetManager.open("cdvasset.manifest"));
                    listCache = (Map<String, String[]>) ois.readObject();
                    lengthCache = (Map<String, Long>) ois.readObject();
                    listCacheFromFile = true;
                } catch (ClassNotFoundException e) {
                    e.printStackTrace();
                } catch (IOException e) {
                    // Asset manifest won't exist if the gradle hook isn't set up correctly.
                } finally {
                    if (ois != null) {
                        try {
                            ois.close();
                        } catch (IOException e) {
                            LOG.d(LOG_TAG, e.getLocalizedMessage());
                        }
                    }
                }
                if (listCache == null) {
                    LOG.w("AssetFilesystem", "Asset manifest not found. Recursive copies and directory listing will be slow.");
                    listCache = new HashMap<String, String[]>();
                }
            }
        }
    }

    private String[] listAssets(String assetPath) throws IOException {
        if (assetPath.startsWith("/")) {
            assetPath = assetPath.substring(1);
        }
        if (assetPath.endsWith("/")) {
            assetPath = assetPath.substring(0, assetPath.length() - 1);
        }
        lazyInitCaches();
        String[] ret = listCache.get(assetPath);
        if (ret == null) {
            if (listCacheFromFile) {
                ret = new String[0];
            } else {
                ret = assetManager.list(assetPath);
                listCache.put(assetPath, ret);
            }
        }
        return ret;
    }

    private long getAssetSize(String assetPath) throws FileNotFoundException {
        if (assetPath.startsWith("/")) {
            assetPath = assetPath.substring(1);
        }
        lazyInitCaches();
        if (lengthCache != null) {
            Long ret = lengthCache.get(assetPath);
            if (ret == null) {
                throw new FileNotFoundException("Asset not found: " + assetPath);
            }
            return ret;
        }
        CordovaResourceApi.OpenForReadResult offr = null;
        try {
            offr = resourceApi.openForRead(nativeUriForFullPath(assetPath));
            long length = offr.length;
            if (length < 0) {
                // available() doesn't always yield the file size, but for assets it does.
                length = offr.inputStream.available();
            }
            return length;
        } catch (IOException e) {
            FileNotFoundException fnfe = new FileNotFoundException("File not found: " + assetPath);
            fnfe.initCause(e);
            throw fnfe;
        } finally {
            if (offr != null) {
                try {
                    offr.inputStream.close();
                } catch (IOException e) {
                    LOG.d(LOG_TAG, e.getLocalizedMessage());
                }
            }
        }
    }

    public AssetFilesystem(AssetManager assetManager, CordovaResourceApi resourceApi, CordovaPreferences preferences) {
        super(Uri.parse("file:///android_asset/"), "assets", resourceApi, preferences);
        this.assetManager = assetManager;
    }

    @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 (isDirectory(subPath) || inputURL.getPath().endsWith("/")) {
            // Add trailing / for directories.
            b.appendEncodedPath("");
        }
        return LocalFilesystemURL.parse(b.build());
    }

    private boolean isDirectory(String assetPath) {
        try {
            return listAssets(assetPath).length != 0;
        } catch (IOException e) {
            return false;
        }
    }

    @Override
    public LocalFilesystemURL[] listChildren(LocalFilesystemURL inputURL) throws FileNotFoundException {
        String pathNoSlashes = inputURL.path.substring(1);
        if (pathNoSlashes.endsWith("/")) {
            pathNoSlashes = pathNoSlashes.substring(0, pathNoSlashes.length() - 1);
        }

        String[] files;
        try {
            files = listAssets(pathNoSlashes);
        } catch (IOException e) {
            FileNotFoundException fnfe = new FileNotFoundException();
            fnfe.initCause(e);
            throw fnfe;
        }

        LocalFilesystemURL[] entries = new LocalFilesystemURL[files.length];
        for (int i = 0; i < files.length; ++i) {
            entries[i] = localUrlforFullPath(new File(inputURL.path, files[i]).getPath());
        }
        return entries;
    }

    @Override
    public JSONObject getFileForLocalURL(LocalFilesystemURL inputURL,
                                         String path, JSONObject options, boolean directory)
            throws FileExistsException, IOException, TypeMismatchException, EncodingException, JSONException {
        if (options != null && options.optBoolean("create")) {
            throw new UnsupportedOperationException("Assets are read-only");
        }

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

        LocalFilesystemURL requestedURL;
        if (path.startsWith("/")) {
            requestedURL = localUrlforFullPath(normalizePath(path));
        } else {
            requestedURL = localUrlforFullPath(normalizePath(inputURL.path + "/" + path));
        }

        // Throws a FileNotFoundException if it doesn't exist.
        getFileMetadataForLocalURL(requestedURL);

        boolean isDir = isDirectory(requestedURL.path);
        if (directory && !isDir) {
            throw new TypeMismatchException("path doesn't exist or is file");
        } else if (!directory && isDir) {
            throw new TypeMismatchException("path doesn't exist or is directory");
        }

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

    @Override
    public JSONObject getFileMetadataForLocalURL(LocalFilesystemURL inputURL) throws FileNotFoundException {
        JSONObject metadata = new JSONObject();
        long size = inputURL.isDirectory ? 0 : getAssetSize(inputURL.path);
        try {
            metadata.put("size", size);
            metadata.put("type", inputURL.isDirectory ? "text/directory" : resourceApi.getMimeType(toNativeUri(inputURL)));
            metadata.put("name", new File(inputURL.path).getName());
            metadata.put("fullPath", inputURL.path);
            metadata.put("lastModifiedDate", 0);
        } catch (JSONException e) {
            return null;
        }
        return metadata;
    }

    @Override
    public boolean canRemoveFileAtLocalURL(LocalFilesystemURL inputURL) {
        return false;
    }

    @Override
    long writeToFileAtURL(LocalFilesystemURL inputURL, String data, int offset, boolean isBinary) throws NoModificationAllowedException, IOException {
        throw new NoModificationAllowedException("Assets are read-only");
    }

    @Override
    long truncateFileAtURL(LocalFilesystemURL inputURL, long size) throws IOException, NoModificationAllowedException {
        throw new NoModificationAllowedException("Assets are read-only");
    }

    @Override
    String filesystemPathForURL(LocalFilesystemURL url) {
        return new File(rootUri.getPath(), url.path).toString();
    }

    @Override
    LocalFilesystemURL URLforFilesystemPath(String path) {
        return null;
    }

    @Override
    boolean removeFileAtLocalURL(LocalFilesystemURL inputURL) throws InvalidModificationException, NoModificationAllowedException {
        throw new NoModificationAllowedException("Assets are read-only");
    }

    @Override
    boolean recursiveRemoveFileAtLocalURL(LocalFilesystemURL inputURL) throws NoModificationAllowedException {
        throw new NoModificationAllowedException("Assets are read-only");
    }

}
