package com.mobify.astro.utilities;

import android.content.ContentResolver;
import android.content.Context;
import android.net.Uri;

import java.net.URISyntaxException;

public class AstroFileUtilities {
    private static final String TAG = AstroFileUtilities.class.getName();

    private static final String ANDROID_ASSETS_PATH = "file:///android_asset/";

    private static final String ASTRO_FILE_SCHEME = "file";

    /**
     * Determines if uri is an Astro File Uri. Must use the Astro File Scheme.
     * @param uri
     * @return True if is an Astro File Uri, False otherwise.
     */
    public static boolean isFileUri(Uri uri) {
        return uri.getScheme().equals(ASTRO_FILE_SCHEME);
    }

    /**
     * Determines if uri is a valid Astro File Uri.
     * Must use the Astro File Scheme and use a triple slash.
     * @param uri
     * @return True if is a valid Astro File Uri, False otherwise.
     */
    public static boolean isValidFileUri(Uri uri) {
        return isFileUri(uri) && uri.getHost().isEmpty();
    }

    /**
     * Create a uri which can be used to retrieve a file from the android assets directory.
     * @param astroResourceUri astro file uri
     * @return A uri which specifies a file in the android assets directory
     * @throws URISyntaxException if the astro file uri is invalid
     */
    public static Uri createAndroidAssetUri(Uri astroResourceUri) throws URISyntaxException {
        return Uri.parse(ANDROID_ASSETS_PATH + getAndroidAssetPath(astroResourceUri));
    }

    /**
     * Retrieve the asset path from an astro file uri
     * @param astroResourceUri astro file uri
     * @return the path of a file inside the android asset directory
     * @throws URISyntaxException if the astro file uri is invalid
     */
    public static String getAndroidAssetPath(Uri astroResourceUri) throws URISyntaxException {
        if (!AstroFileUtilities.isValidFileUri(astroResourceUri)) {
            throw new URISyntaxException(astroResourceUri.toString(), "Invalid Astro file Uri");
        }
        String path = astroResourceUri.getPath();

        // The leading slash caused issues when retrieving the bitmap
        // Strip off the leading slash
        if (path.startsWith("/")) {
            path = path.substring(1);
        }

        // Add back the url fragment if there is one
        String fragment = astroResourceUri.getFragment();
        if (fragment != null && fragment.length() > 0) {
            path = path + "#" + fragment;
        }

        return path;
    }

    /**
     * Create a uri which can be used to retrieve a file from the resource drawable directory.
     * @param astroResourceUri astro file uri
     * @param resourcePackageName package name for the android resource
     * @return A uri which specifies a file in the android resource drawable directory
     * @throws URISyntaxException if the astro file uri is invalid
     */
    public static Uri getAndroidResourceDrawableUri (
            Uri astroResourceUri, String resourcePackageName) throws URISyntaxException {
        if (!AstroFileUtilities.isValidFileUri(astroResourceUri)) {
            throw new URISyntaxException(astroResourceUri.toString(), "Invalid Astro file Uri");
        }

        String resourceFileName = getResourceFileName(astroResourceUri);

        // Create the uri necessary to find the image in the android
        // resources directory
        //
        // We are assuming the resource is in the app's package
        // and is a drawable resource
        //
        // Ignore any leading directories in the astroResourceUri
        String androidResourceUri = ContentResolver.SCHEME_ANDROID_RESOURCE + "://"
                + resourcePackageName + "/drawable/"
                + resourceFileName;

        return Uri.parse(androidResourceUri);
    }

    /**
     * Returns a resource identifier representing the drawable identified by the astroResourceUri
     * @param context context from the package containing the drawable resource
     * @param astroResourceUri astro file uri
     * @return a resource identifier representing the drawable identified by the astroResourceUri
     * @throws URISyntaxException if the astro file uri is invalid
     */
    public static int getAndroidResourceDrawableIdentifier(Context context, Uri astroResourceUri) throws URISyntaxException {
        if (!AstroFileUtilities.isValidFileUri(astroResourceUri)) {
            throw new URISyntaxException(astroResourceUri.toString(), "Invalid Astro file Uri");
        }

        String resourceFileName = getResourceFileName(astroResourceUri);

        return context.getResources().getIdentifier(resourceFileName, "drawable", context.getPackageName());
    }

    private static String getResourceFileName(Uri astroResourceUri) {
        String resourceFileName = astroResourceUri.getLastPathSegment();

        // Strip off the extension, asset won't be found if an extension exists
        int indexOfPeriod = resourceFileName.lastIndexOf(".");
        if (indexOfPeriod != -1) {
            resourceFileName = resourceFileName.substring(0, indexOfPeriod);
        }

        return resourceFileName;
    }
}
