/*
 * Copyright (C) 2017 The Android Open Source Project
 *
 * Licensed 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 com.google.android.exoplayer2.upstream;

import android.content.ContentProvider;
import android.content.ContentResolver;
import android.content.ContentValues;
import android.content.res.AssetFileDescriptor;
import android.database.Cursor;
import android.net.Uri;
import android.support.annotation.NonNull;
import android.test.InstrumentationTestCase;
import android.test.MoreAsserts;
import com.google.android.exoplayer2.C;
import com.google.android.exoplayer2.testutil.TestUtil;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.Arrays;

/**
 * Unit tests for {@link ContentDataSource}.
 */
public final class ContentDataSourceTest extends InstrumentationTestCase {

  private static final String AUTHORITY = "com.google.android.exoplayer2.core.test";
  private static final String DATA_PATH = "binary/1024_incrementing_bytes.mp3";

  private static final int TEST_DATA_OFFSET = 1;
  private static final int TEST_DATA_LENGTH = 1023;

  public void testReadValidUri() throws Exception {
    ContentDataSource dataSource = new ContentDataSource(getInstrumentation().getContext());
    Uri contentUri = new Uri.Builder()
        .scheme(ContentResolver.SCHEME_CONTENT)
        .authority(AUTHORITY)
        .path(DATA_PATH).build();
    DataSpec dataSpec = new DataSpec(contentUri);
    TestUtil.assertDataSourceContent(dataSource, dataSpec,
        TestUtil.getByteArray(getInstrumentation(), DATA_PATH));
  }

  public void testReadInvalidUri() throws Exception {
    ContentDataSource dataSource = new ContentDataSource(getInstrumentation().getContext());
    Uri contentUri = new Uri.Builder()
        .scheme(ContentResolver.SCHEME_CONTENT)
        .authority(AUTHORITY)
        .build();
    DataSpec dataSpec = new DataSpec(contentUri);
    try {
      dataSource.open(dataSpec);
      fail();
    } catch (ContentDataSource.ContentDataSourceException e) {
      // Expected.
      assertTrue(e.getCause() instanceof FileNotFoundException);
    } finally {
      dataSource.close();
    }
  }

  public void testReadFromOffsetToEndOfInput() throws Exception {
    ContentDataSource dataSource = new ContentDataSource(getInstrumentation().getContext());
    Uri contentUri = new Uri.Builder()
        .scheme(ContentResolver.SCHEME_CONTENT)
        .authority(AUTHORITY)
        .path(DATA_PATH).build();
    try {
      DataSpec dataSpec = new DataSpec(contentUri, TEST_DATA_OFFSET, C.LENGTH_UNSET, null);
      long length = dataSource.open(dataSpec);
      assertEquals(TEST_DATA_LENGTH, length);
      byte[] expectedData = Arrays.copyOfRange(
          TestUtil.getByteArray(getInstrumentation(), DATA_PATH), TEST_DATA_OFFSET,
          TEST_DATA_OFFSET + TEST_DATA_LENGTH);
      byte[] readData = TestUtil.readToEnd(dataSource);
      MoreAsserts.assertEquals(expectedData, readData);
      assertEquals(C.RESULT_END_OF_INPUT, dataSource.read(new byte[1], 0, 1));
    } finally {
      dataSource.close();
    }
  }

  /**
   * A {@link ContentProvider} for the test.
   */
  public static final class TestContentProvider extends ContentProvider {

    @Override
    public boolean onCreate() {
      return true;
    }

    @Override
    public Cursor query(@NonNull Uri uri, String[] projection, String selection,
        String[] selectionArgs, String sortOrder) {
      throw new UnsupportedOperationException();
    }

    @Override
    public AssetFileDescriptor openAssetFile(@NonNull Uri uri, @NonNull String mode)
        throws FileNotFoundException {
      if (uri.getPath() == null) {
        return null;
      }
      try {
        return getContext().getAssets().openFd(uri.getPath().replaceFirst("/", ""));
      } catch (IOException e) {
        FileNotFoundException exception = new FileNotFoundException(e.getMessage());
        exception.initCause(e);
        throw exception;
      }
    }

    @Override
    public String getType(@NonNull Uri uri) {
      throw new UnsupportedOperationException();
    }

    @Override
    public Uri insert(@NonNull Uri uri, ContentValues values) {
      throw new UnsupportedOperationException();
    }

    @Override
    public int delete(@NonNull Uri uri, String selection,
        String[] selectionArgs) {
      throw new UnsupportedOperationException();
    }

    @Override
    public int update(@NonNull Uri uri, ContentValues values,
        String selection, String[] selectionArgs) {
      throw new UnsupportedOperationException();
    }

  }

}

@@ -976,41 +976,8 @@
 se;%0A
-import android.test.MoreAsserts;%0A
 impo
@@ -1459,110 +1459,8 @@
 %22;%0A%0A
-  private static final int TEST_DATA_OFFSET = 1;%0A  private static final int TEST_DATA_LENGTH = 1023;%0A%0A
   pu
@@ -2835,24 +2835,50 @@
 ;%0A    try %7B%0A
+      int testOffset = 1;%0A
       DataSp
@@ -2916,32 +2916,26 @@
 entUri, 
-TEST_DATA_OFFSET
+testOffset
 , C.LENG
@@ -2955,101 +2955,8 @@
 l);%0A
-      long length = dataSource.open(dataSpec);%0A      assertEquals(TEST_DATA_LENGTH, length);%0A
     
@@ -2968,52 +2968,22 @@
 e%5B%5D 
-expec
+comple
 te
-d
 Data =
- Arrays.copyOfRange(%0A         
  Tes
@@ -3037,74 +3037,8 @@
 ATH)
-, TEST_DATA_OFFSET,%0A          TEST_DATA_OFFSET + TEST_DATA_LENGTH)
 ;%0A  
@@ -3052,19 +3052,23 @@
 e%5B%5D 
-rea
+expecte
 dData = 
 Test
@@ -3067,172 +3067,148 @@
 a = 
-TestUtil.readToEnd(dataSource);%0A      MoreAsserts.assertEquals(expec
+Arrays.copyOfRange(completeData, testOffset, comple
 te
-d
 Data
-, readData);%0A      assertEquals(C.RESULT_END_OF_INPUT, dataSource.read(new byte%5B1%5D, 0, 1)
+.length);%0A      TestUtil.assertDataSourceContent(dataSource, dataSpec, expectedData
 );%0A 

Simplify ContentDataSourceTest