/*
 * Copyright (C) 2012 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.
 */

#include <iostream>
#include <iomanip>
#include <gtest/gtest.h>

#define LOG_TAG "CameraStreamTest"
#define LOG_NDEBUG 0
#include <utils/Log.h>

#include "hardware/hardware.h"
#include "hardware/camera2.h"

#include <utils/StrongPointer.h>
#include <gui/CpuConsumer.h>
#include <gui/Surface.h>

#include <device2/Camera2Device.h>

#include "CameraStreamFixture.h"
#include "TestExtensions.h"

using namespace android;
using namespace android::camera2;

namespace android {
namespace camera2 {
namespace tests {

class CameraStreamTest
    : public ::testing::TestWithParam<CameraStreamParams>,
      public CameraStreamFixture {

public:
    CameraStreamTest() : CameraStreamFixture(GetParam()) {
        TEST_EXTENSION_FORKING_CONSTRUCTOR;
    }

    ~CameraStreamTest() {
        TEST_EXTENSION_FORKING_DESTRUCTOR;
    }

    virtual void SetUp() {
        TEST_EXTENSION_FORKING_SET_UP;
    }
    virtual void TearDown() {
        TEST_EXTENSION_FORKING_TEAR_DOWN;
    }

protected:

};

TEST_P(CameraStreamTest, CreateStream) {

    TEST_EXTENSION_FORKING_INIT;

    /** Make sure the format requested is supported. PASS this test if it's not
      * not supported.
      *
      * TODO: would be nice of not running this test in the first place
      *       somehow.
      */
    {
        camera_metadata_ro_entry availableFormats =
            GetStaticEntry(ANDROID_SCALER_AVAILABLE_FORMATS);

        bool hasFormat = false;
        for (size_t i = 0; i < availableFormats.count; ++i) {
            if (availableFormats.data.i32[i] == GetParam().mFormat) {
                hasFormat = true;
                break;
            }
        }

        if (!hasFormat) {
            const ::testing::TestInfo* const test_info =
                ::testing::UnitTest::GetInstance()->current_test_info();
            std::cerr << "Skipping test "
                      << test_info->test_case_name() << "."
                      << test_info->name()
                      << " because the format was not available: "
                      << GetParam() << std::endl;
            return;
        }
    }

    ASSERT_NO_FATAL_FAILURE(CreateStream());
    ASSERT_NO_FATAL_FAILURE(DeleteStream());
}

//TODO: use a combinatoric generator
static CameraStreamParams TestParameters[] = {
    {
        /*mFormat*/    HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED,
        /*mHeapCount*/ 1
    },
    {
        /*mFormat*/    HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED,
        /*mHeapCount*/ 2
    },
    {
        /*mFormat*/    HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED,
        /*mHeapCount*/ 3
    },
    {
        /*mFormat*/    HAL_PIXEL_FORMAT_YCrCb_420_SP, // NV21
        /*mHeapCount*/ 1
    },
    {
        /*mFormat*/    HAL_PIXEL_FORMAT_YCrCb_420_SP,
        /*mHeapCount*/ 2
    },
    {
        /*mFormat*/    HAL_PIXEL_FORMAT_YCrCb_420_SP,
        /*mHeapCount*/ 3
    },
    {
        /*mFormat*/    HAL_PIXEL_FORMAT_YV12,
        /*mHeapCount*/ 1
    },
    {
        /*mFormat*/    HAL_PIXEL_FORMAT_YV12,
        /*mHeapCount*/ 2
    },
    {
        /*mFormat*/    HAL_PIXEL_FORMAT_YV12,
        /*mHeapCount*/ 3
    },
    {
        /*mFormat*/    HAL_PIXEL_FORMAT_Y8,
        /*mHeapCount*/ 1
    },
    {
        /*mFormat*/    HAL_PIXEL_FORMAT_Y8,
        /*mHeapCount*/ 2
    },
    {
        /*mFormat*/    HAL_PIXEL_FORMAT_Y8,
        /*mHeapCount*/ 3
    },
    {
        /*mFormat*/    HAL_PIXEL_FORMAT_Y16,
        /*mHeapCount*/ 1
    },
    {
        /*mFormat*/    HAL_PIXEL_FORMAT_Y16,
        /*mHeapCount*/ 2
    },
    {
        /*mFormat*/    HAL_PIXEL_FORMAT_Y16,
        /*mHeapCount*/ 3
    },
    {
        /*mFormat*/    HAL_PIXEL_FORMAT_RAW16,
        /*mHeapCount*/ 1
    },
    {
        /*mFormat*/    HAL_PIXEL_FORMAT_RAW16,
        /*mHeapCount*/ 2
    },
    {
        /*mFormat*/    HAL_PIXEL_FORMAT_RAW16,
        /*mHeapCount*/ 3
    },
};

INSTANTIATE_TEST_CASE_P(StreamParameterCombinations, CameraStreamTest,
    testing::ValuesIn(TestParameters));


}
}
}
