
package org.apache.cordova.test;

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

import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.os.Environment;
import android.provider.MediaStore;
import android.test.ActivityInstrumentationTestCase2;

import org.apache.cordova.CallbackContext;
import org.apache.cordova.CordovaPlugin;
import org.apache.cordova.CordovaResourceApi;
import org.apache.cordova.CordovaResourceApi.OpenForReadResult;
import org.apache.cordova.CordovaWebView;
import org.apache.cordova.PluginEntry;
import org.apache.cordova.test.actions.CordovaWebViewTestActivity;
import org.json.JSONArray;
import org.json.JSONException;

import java.io.File;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Scanner;

public class CordovaResourceApiTest extends ActivityInstrumentationTestCase2<CordovaWebViewTestActivity> {

    public CordovaResourceApiTest()
    {
        super(CordovaWebViewTestActivity.class);
    }

    CordovaWebView cordovaWebView;
    CordovaResourceApi resourceApi;

    private CordovaWebViewTestActivity activity;
    String execPayload;
    Integer execStatus;

    protected void setUp() throws Exception {
        super.setUp();
        activity = this.getActivity();
        cordovaWebView = activity.cordovaWebView;
        resourceApi = cordovaWebView.getResourceApi();
        resourceApi.setThreadCheckingEnabled(false);
        cordovaWebView.pluginManager.addService(new PluginEntry("CordovaResourceApiTestPlugin1", new CordovaPlugin() {
            @Override
            public Uri remapUri(Uri uri) {
                if (uri.getQuery() != null && uri.getQuery().contains("pluginRewrite")) {
                    return cordovaWebView.getResourceApi().remapUri(
                            Uri.parse("data:text/plain;charset=utf-8,pass"));
                }
                return null;
            }
            public boolean execute(String action, JSONArray args, CallbackContext callbackContext) throws JSONException {
                synchronized (CordovaResourceApiTest.this) {
                    execPayload = args.getString(0);
                    execStatus = args.getInt(1);
                    CordovaResourceApiTest.this.notify();
                }
                return true;
            }
        }));
    }

    private Uri createTestImageContentUri() {
        Bitmap imageBitmap = BitmapFactory.decodeResource(activity.getResources(), R.drawable.icon);
        String stored = MediaStore.Images.Media.insertImage(activity.getContentResolver(),
                imageBitmap, "app-icon", "desc");
        return Uri.parse(stored);
    }

    private void performApiTest(Uri uri, String expectedMimeType, File expectedLocalFile,
            boolean expectRead, boolean expectWrite) throws IOException {
        uri = resourceApi.remapUri(uri);
        assertEquals(expectedLocalFile, resourceApi.mapUriToFile(uri));
        
        try {
            OpenForReadResult readResult = resourceApi.openForRead(uri);
            String mimeType2 = resourceApi.getMimeType(uri);
            assertEquals("openForRead mime-type", expectedMimeType, readResult.mimeType);
            assertEquals("getMimeType mime-type", expectedMimeType, mimeType2);
            readResult.inputStream.read();
            if (!expectRead) {
                fail("Expected getInputStream to throw.");
            }
        } catch (IOException e) {
            if (expectRead) {
                throw e;
            }
        }
        try {
            OutputStream outStream = resourceApi.openOutputStream(uri);
            outStream.write(123);
            if (!expectWrite) {
                fail("Expected getOutputStream to throw.");
            }
            outStream.close();
        } catch (IOException e) {
            if (expectWrite) {
                throw e;
            }
        }
    }

    public void testValidContentUri() throws IOException
    {
        Uri contentUri = createTestImageContentUri();
        File localFile = resourceApi.mapUriToFile(contentUri);
        assertNotNull(localFile);
        performApiTest(contentUri, "image/jpeg", localFile, true, true);
    }

    public void testInvalidContentUri() throws IOException
    {
        Uri contentUri = Uri.parse("content://media/external/images/media/999999999");
        performApiTest(contentUri, null, null, false, false);
    }

    public void testValidAssetUri() throws IOException
    {
        Uri assetUri = Uri.parse("file:///android_asset/www/index.html?foo#bar"); // Also check for stripping off ? and # correctly.
        performApiTest(assetUri, "text/html", null, true, false);
    }

    public void testInvalidAssetUri() throws IOException
    {
        Uri assetUri = Uri.parse("file:///android_asset/www/missing.html");
        performApiTest(assetUri, "text/html", null, false, false);
    }

    public void testFileUriToExistingFile() throws IOException
    {
        File f = File.createTempFile("te s t", ".txt"); // Also check for dealing with spaces.
        try {
            Uri fileUri = Uri.parse(f.toURI().toString() + "?foo#bar"); // Also check for stripping off ? and # correctly.
            performApiTest(fileUri, "text/plain", f, true, true);
        } finally {
            f.delete();
        }
    }

    public void testFileUriToMissingFile() throws IOException
    {
        File f = new File(Environment.getExternalStorageDirectory() + "/somefilethatdoesntexist");
        Uri fileUri = Uri.parse(f.toURI().toString());
        try {
            performApiTest(fileUri, null, f, false, true);
        } finally {
            f.delete();
        }
    }
    
    public void testFileUriToMissingFileWithMissingParent() throws IOException
    {
        File f = new File(Environment.getExternalStorageDirectory() + "/somedirthatismissing" + System.currentTimeMillis() + "/somefilethatdoesntexist");
        Uri fileUri = Uri.parse(f.toURI().toString());
        performApiTest(fileUri, null, f, false, true);
    }

    public void testUnrecognizedUri() throws IOException
    {
        Uri uri = Uri.parse("somescheme://foo");
        performApiTest(uri, null, null, false, false);
    }

    public void testRelativeUri()
    {
        try {
            resourceApi.openForRead(Uri.parse("/foo"));
            fail("Should have thrown for relative URI 1.");
        } catch (Throwable t) {
        }
        try {
            resourceApi.openForRead(Uri.parse("//foo/bar"));
            fail("Should have thrown for relative URI 2.");
        } catch (Throwable t) {
        }
        try {
            resourceApi.openForRead(Uri.parse("foo.png"));
            fail("Should have thrown for relative URI 3.");
        } catch (Throwable t) {
        }
    }
    
    public void testPluginOverride() throws IOException
    {
        Uri uri = Uri.parse("plugin-uri://foohost/android_asset/www/index.html?pluginRewrite=yes");
        performApiTest(uri, "text/plain", null, true, false);
    }

    public void testMainThreadUsage() throws IOException
    {
        Uri assetUri = Uri.parse("file:///android_asset/www/index.html");
        resourceApi.setThreadCheckingEnabled(true);
        try {
            resourceApi.openForRead(assetUri);
            fail("Should have thrown for main thread check.");
        } catch (Throwable t) {
        }
    }
    
    
    public void testDataUriPlain() throws IOException
    {
        Uri uri = Uri.parse("data:text/plain;charset=utf-8,pa%20ss");
        OpenForReadResult readResult = resourceApi.openForRead(uri);
        assertEquals("text/plain", readResult.mimeType);
        String data = new Scanner(readResult.inputStream, "UTF-8").useDelimiter("\\A").next();
        assertEquals("pa ss", data);
    }
    
    public void testDataUriBase64() throws IOException
    {
        Uri uri = Uri.parse("data:text/js;charset=utf-8;base64,cGFzcw==");
        OpenForReadResult readResult = resourceApi.openForRead(uri);
        assertEquals("text/js", readResult.mimeType);
        String data = new Scanner(readResult.inputStream, "UTF-8").useDelimiter("\\A").next();
        assertEquals("pass", data);
    }
    
    public void testWebViewRequestIntercept() throws IOException
    {
        cordovaWebView.sendJavascript(
            "var x = new XMLHttpRequest;\n" +
            "x.open('GET', 'file://foo?pluginRewrite=1', false);\n" + 
            "x.send();\n" + 
            "cordova.require('cordova/exec')(null,null,'CordovaResourceApiTestPlugin1', 'foo', [x.responseText, x.status])");
        
        execPayload = null;
        execStatus = null;
        try {
            synchronized (this) {
                this.wait(2000);
            }
        } catch (InterruptedException e) {
        }
        assertEquals("pass", execPayload);
        assertEquals(execStatus.intValue(), 200);
    }
    
    public void testWebViewWhiteListRejection() throws IOException
    {
        cordovaWebView.sendJavascript(
            "var x = new XMLHttpRequest;\n" +
            "x.open('GET', 'http://foo/bar', false);\n" + 
            "x.send();\n" + 
            "cordova.require('cordova/exec')(null,null,'CordovaResourceApiTestPlugin1', 'foo', [x.responseText, x.status])");
        execPayload = null;
        execStatus = null;
        try {
            synchronized (this) {
                this.wait(2000);
            }
        } catch (InterruptedException e) {
        }
        assertEquals("", execPayload);
        assertEquals(execStatus.intValue(), 404);
    }    
}
