/*
       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.CordovaResourceApi;
import org.apache.cordova.LOG;
import org.json.JSONArray;
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) {
        super(Uri.parse("file:///android_asset/"), "assets", resourceApi);
        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 = new Uri.Builder()
            .scheme(LocalFilesystemURL.FILESYSTEM_PROTOCOL)
            .authority("localhost")
            .path(name);
        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");
    }

}
