/*
 * Copyright (C) 2020 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.android.systemui.glwallpaper;

import static com.android.systemui.glwallpaper.GLWallpaperRenderer.SurfaceProxy;

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

import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.spy;

import android.app.WallpaperManager;
import android.app.WallpaperManager.ColorManagementProxy;
import android.graphics.Bitmap;
import android.graphics.ColorSpace;
import android.testing.AndroidTestingRunner;
import android.testing.TestableLooper;

import androidx.test.filters.SmallTest;

import com.android.systemui.SysuiTestCase;

import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;

import java.io.IOException;
import java.util.HashSet;
import java.util.Set;

@SmallTest
@RunWith(AndroidTestingRunner.class)
@TestableLooper.RunWithLooper(setAsMainLooper = true)
public class ImageWallpaperRendererTest extends SysuiTestCase {

    private WallpaperManager mWpmSpy;
    private SurfaceProxy mSurfaceProxy;

    @Before
    public void setUp() throws Exception {
        final WallpaperManager wpm = mContext.getSystemService(WallpaperManager.class);
        mWpmSpy = spy(wpm);
        mContext.addMockSystemService(WallpaperManager.class, mWpmSpy);

        mSurfaceProxy = new SurfaceProxy() {
            @Override
            public void requestRender() {
                // NO-op
            }

            @Override
            public void preRender() {
                // No-op
            }

            @Override
            public void postRender() {
                // No-op
            }
        };
    }

    @Test
    public void testWcgContent() throws IOException {
        final Bitmap srgbBitmap = Bitmap.createBitmap(100, 100, Bitmap.Config.ARGB_8888);
        final Bitmap p3Bitmap = Bitmap.createBitmap(100, 100, Bitmap.Config.ARGB_8888,
                false /* hasAlpha */, ColorSpace.get(ColorSpace.Named.DISPLAY_P3));

        final ColorManagementProxy proxy = new ColorManagementProxy(mContext);
        final ColorManagementProxy cmProxySpy = spy(proxy);
        final Set<ColorSpace> supportedWideGamuts = new HashSet<>();
        supportedWideGamuts.add(ColorSpace.get(ColorSpace.Named.DISPLAY_P3));

        try {
            doReturn(true).when(mWpmSpy).shouldEnableWideColorGamut();
            doReturn(cmProxySpy).when(mWpmSpy).getColorManagementProxy();
            doReturn(supportedWideGamuts).when(cmProxySpy).getSupportedColorSpaces();

            mWpmSpy.setBitmap(p3Bitmap);
            ImageWallpaperRenderer rendererP3 = new ImageWallpaperRenderer(mContext, mSurfaceProxy);
            rendererP3.reportSurfaceSize();
            assertThat(rendererP3.isWcgContent()).isTrue();

            mWpmSpy.setBitmap(srgbBitmap);
            ImageWallpaperRenderer renderer = new ImageWallpaperRenderer(mContext, mSurfaceProxy);
            assertThat(renderer.isWcgContent()).isFalse();
        } finally {
            srgbBitmap.recycle();
            p3Bitmap.recycle();
        }
    }

}
