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

#include <gtest/gtest.h>

#include <gui/SurfaceComposerClient.h>

#include <utils/String8.h>

#include <thread>
#include <functional>
#include <layerproto/LayerProtoParser.h>

namespace android {

TEST(SurfaceFlingerStress, create_and_destroy) {
    auto do_stress = []() {
        sp<SurfaceComposerClient> client = new SurfaceComposerClient;
        ASSERT_EQ(NO_ERROR, client->initCheck());
        for (int j = 0; j < 1000; j++) {
            auto surf = client->createSurface(String8("t"), 100, 100,
                    PIXEL_FORMAT_RGBA_8888, 0);
            ASSERT_TRUE(surf != nullptr);
            client->destroySurface(surf->getHandle());
        }
    };

    std::vector<std::thread> threads;
    for (int i = 0; i < 10; i++) {
        threads.push_back(std::thread(do_stress));
    }
    for (auto& thread : threads) {
        thread.join();
    }
}

surfaceflinger::LayersProto generateLayerProto() {
    surfaceflinger::LayersProto layersProto;
    std::array<surfaceflinger::LayerProto*, 10> layers = {};
    for (size_t i = 0; i < layers.size(); ++i) {
        layers[i] = layersProto.add_layers();
        layers[i]->set_id(i);
    }

    layers[0]->add_children(1);
    layers[1]->set_parent(0);
    layers[0]->add_children(2);
    layers[2]->set_parent(0);
    layers[0]->add_children(3);
    layers[3]->set_parent(0);
    layers[2]->add_children(4);
    layers[4]->set_parent(2);
    layers[3]->add_children(5);
    layers[5]->set_parent(3);
    layers[5]->add_children(6);
    layers[6]->set_parent(5);
    layers[5]->add_children(7);
    layers[7]->set_parent(5);
    layers[6]->add_children(8);
    layers[8]->set_parent(6);

    layers[4]->set_z_order_relative_of(3);
    layers[3]->add_relatives(4);
    layers[8]->set_z_order_relative_of(9);
    layers[9]->add_relatives(8);
    layers[3]->set_z_order_relative_of(1);
    layers[1]->add_relatives(3);

/* ----------------------------
 *       - 0 -      - 9 -
 *      /  |  \
 *     1   2   3(1)
 *         |    |
 *         4(3) 5
 *             / \
 *            6   7
 *            |
 *            8(9)
 * -------------------------- */

    return layersProto;
}

TEST(LayerProtoStress, mem_info) {
    std::string cmd = "dumpsys meminfo ";
    cmd += std::to_string(getpid());
    system(cmd.c_str());
    for (int i = 0; i < 100000; i++) {
        surfaceflinger::LayersProto layersProto = generateLayerProto();
        auto layerTree = surfaceflinger::LayerProtoParser::generateLayerTree(layersProto);
        // Allow some layerTrees to just fall out of scope (instead of std::move)
        if (i % 2) {
            surfaceflinger::LayerProtoParser::layersToString(std::move(layerTree));
        }
    }
    system(cmd.c_str());
}

}
