/*
 * Copyright (C) 2021 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 android.photopicker.cts;

import static android.photopicker.cts.util.PhotoPickerAssertionsUtils.assertPickerUriFormat;
import static android.photopicker.cts.util.PhotoPickerAssertionsUtils.assertRedactedReadOnlyAccess;
import static android.photopicker.cts.util.PhotoPickerFilesUtils.createImagesAndGetUris;
import static android.photopicker.cts.util.PhotoPickerFilesUtils.deleteMedia;
import static android.photopicker.cts.util.PhotoPickerUiUtils.SHORT_TIMEOUT;
import static android.photopicker.cts.util.PhotoPickerUiUtils.findAddButton;
import static android.photopicker.cts.util.PhotoPickerUiUtils.findItemList;
import static android.photopicker.cts.util.PhotoPickerUiUtils.findProfileButton;

import static com.google.common.truth.Truth.assertThat;
import static com.google.common.truth.Truth.assertWithMessage;

import android.content.ClipData;
import android.content.Intent;
import android.net.Uri;
import android.provider.MediaStore;

import androidx.test.filters.SdkSuppress;
import androidx.test.uiautomator.UiObject;
import androidx.test.uiautomator.UiSelector;

import com.android.bedstead.harrier.BedsteadJUnit4;
import com.android.bedstead.harrier.DeviceState;
import com.android.bedstead.harrier.annotations.EnsureHasWorkProfile;
import com.android.bedstead.harrier.annotations.RequireRunOnWorkProfile;

import org.junit.After;
import org.junit.ClassRule;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;

import java.util.ArrayList;
import java.util.List;

/**
 * Photo Picker Device only tests for cross profile interaction flows.
 */
@RunWith(BedsteadJUnit4.class)
public class PhotoPickerCrossProfileTest extends PhotoPickerBaseTest {
    @ClassRule @Rule
    public static final DeviceState sDeviceState = new DeviceState();

    private List<Uri> mUriList = new ArrayList<>();

    @After
    public void tearDown() throws Exception {
        for (Uri uri : mUriList) {
            deleteMedia(uri, mContext);
        }
        mUriList.clear();
        mActivity.finish();
    }

    /**
     * ACTION_PICK_IMAGES is allowlisted by default from work to personal. This got allowlisted
     * in a platform code change and is available Android T onwards.
     */
    @Test
    @RequireRunOnWorkProfile
    @SdkSuppress(minSdkVersion = 32, codeName = "T")
    public void testWorkApp_canAccessPersonalProfileContents() throws Exception {
        final int imageCount = 2;
        mUriList.addAll(createImagesAndGetUris(imageCount, sDeviceState.primaryUser().id()));

        Intent intent = new Intent(MediaStore.ACTION_PICK_IMAGES);
        intent.putExtra(MediaStore.EXTRA_PICK_IMAGES_MAX, imageCount);
        mActivity.startActivityForResult(intent, REQUEST_CODE);

        // Click the profile button to change to personal profile
        final UiObject profileButton = findProfileButton();
        profileButton.click();
        mDevice.waitForIdle();

        final List<UiObject> itemList = findItemList(imageCount);
        final int itemCount = itemList.size();
        assertThat(itemCount).isEqualTo(imageCount);
        for (int i = 0; i < itemCount; i++) {
            final UiObject item = itemList.get(i);
            item.click();
            mDevice.waitForIdle();
        }

        final UiObject addButton = findAddButton();
        addButton.click();
        mDevice.waitForIdle();

        final ClipData clipData = mActivity.getResult().data.getClipData();
        final int count = clipData.getItemCount();
        assertThat(count).isEqualTo(imageCount);
        for (int i = 0; i < count; i++) {
            Uri uri = clipData.getItemAt(i).getUri();
            assertPickerUriFormat(uri, sDeviceState.primaryUser().id());
            assertRedactedReadOnlyAccess(uri);
        }
    }

    /**
     * ACTION_PICK_IMAGES is allowlisted by default from work to personal. This got allowlisted
     * in a platform code change and is available Android T onwards. Before that it needs to be
     * explicitly allowlisted by the device admin.
     */
    @Test
    @RequireRunOnWorkProfile
    @SdkSuppress(maxSdkVersion = 31, codeName = "S")
    public void testWorkApp_cannotAccessPersonalProfile_beforeT() throws Exception {
        assertBlockedByAdmin(/* isInvokedFromWorkProfile */ true);
    }

    /**
     * ACTION_PICK_IMAGES is allowlisted by default from work to personal only (not vice-a-versa)
     */
    @Test
    @EnsureHasWorkProfile
    public void testPersonalApp_cannotAccessWorkProfile_default() throws Exception {
        assertBlockedByAdmin(/* isInvokedFromWorkProfile */ false);
    }

    private void assertBlockedByAdmin(boolean isInvokedFromWorkProfile) throws Exception {
        Intent intent = new Intent(MediaStore.ACTION_PICK_IMAGES);
        intent.putExtra(MediaStore.EXTRA_PICK_IMAGES_MAX, MediaStore.getPickImagesMaxLimit());
        mActivity.startActivityForResult(intent, REQUEST_CODE);

        // Click the profile button to change to work profile
        final UiObject profileButton = findProfileButton();
        profileButton.click();
        mDevice.waitForIdle();

        assertBlockedByAdminDialog(isInvokedFromWorkProfile);
    }

    private void assertBlockedByAdminDialog(boolean isInvokedFromWorkProfile) {
        final String dialogTitle = "Blocked by your admin";
        assertWithMessage("Timed out while waiting for blocked by admin dialog to appear")
                .that(new UiObject(new UiSelector().textContains(dialogTitle))
                        .waitForExists(SHORT_TIMEOUT))
                .isTrue();

        final String dialogDescription;
        if (isInvokedFromWorkProfile) {
            dialogDescription = "Accessing personal data from a work app is not permitted";
        } else {
            dialogDescription = "Accessing work data from a personal app is not permitted";
        }
        assertWithMessage("Blocked by admin description is not as expected")
                .that(new UiObject(new UiSelector().textContains(dialogDescription)).exists())
                .isTrue();
    }
}
