/*
 * Copyright 2017 Google Inc.
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

package org.skia.skqp;

import android.content.Context;
import android.content.res.AssetManager;
import android.content.res.Resources;
import android.util.Log;
import androidx.test.InstrumentationRegistry;
import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import org.junit.runner.Description;
import org.junit.runner.RunWith;
import org.junit.runner.Runner;
import org.junit.runner.manipulation.Filter;
import org.junit.runner.manipulation.Filterable;
import org.junit.runner.manipulation.NoTestsRemainException;
import org.junit.runner.notification.Failure;
import org.junit.runner.notification.RunNotifier;

@RunWith(SkQPRunner.class)
public class SkQPRunner extends Runner implements Filterable {
    private int mShouldRunTestCount;
    private Description[] mTests;
    private boolean[] mShouldSkipTest;
    private String mOutputDirectory;
    private SkQP mImpl;
    private static final String TAG = SkQP.LOG_PREFIX;

    private static void Fail(Description desc, RunNotifier notifier, String failure) {
        notifier.fireTestFailure(new Failure(desc, new SkQPFailure(failure)));
    }

    ////////////////////////////////////////////////////////////////////////////

    public SkQPRunner(Class testClass) {
        mImpl = new SkQP();
        Context context = InstrumentationRegistry.getTargetContext();
        String now = (new SimpleDateFormat("yyyy-MM-dd'T'HHmmss")).format(new Date());
        File reportPath = new File(context.getExternalFilesDir(null), "skqp_report_" + now);
        reportPath.mkdirs();
        mOutputDirectory = reportPath.getAbsolutePath();
        Log.i(TAG, String.format("output written to \"%s\"", mOutputDirectory));

        AssetManager assetManager = context.getResources().getAssets();
        mImpl.nInit(assetManager, mOutputDirectory);

        mTests = new Description[this.testCount()];
        mShouldSkipTest = new boolean[mTests.length]; // = {false, false, ....};
        int index = 0;
        for (int backend = 0; backend < mImpl.mBackends.length; backend++) {
            for (int gm = 0; gm < mImpl.mGMs.length; gm++) {
                mTests[index++] = Description.createTestDescription(SkQPRunner.class,
                    mImpl.mBackends[backend] + "_" + mImpl.mGMs[gm]);
            }
        }
        for (int unitTest = 0; unitTest < mImpl.mUnitTests.length; unitTest++) {
            mTests[index++] = Description.createTestDescription(SkQPRunner.class,
                    "unitTest_" + mImpl.mUnitTests[unitTest]);
        }
        assert(index == mTests.length);
        mShouldRunTestCount = mTests.length;
    }

    @Override
    public void filter(Filter filter) throws NoTestsRemainException {
        int count = 0;
        for (int i = 0; i < mTests.length; ++i) {
            mShouldSkipTest[i] = !filter.shouldRun(mTests[i]);
            if (!mShouldSkipTest[i]) {
                ++count;
            }
        }
        mShouldRunTestCount = count;
        if (0 == count) {
            throw new NoTestsRemainException();
        }
    }

    @Override
    public Description getDescription() {
        Description d = Description.createSuiteDescription(SkQP.class);
        for (int i = 0; i < mTests.length; ++i) {
            d.addChild(mTests[i]);
        }
        return d;
    }

    @Override
    public int testCount() {
        return mImpl.mUnitTests.length + mImpl.mGMs.length * mImpl.mBackends.length;
    }

    @Override
    public void run(RunNotifier notifier) {
        int testNumber = 0;  // out of number of actually run tests.
        int testIndex = 0;  // out of potential tests.
        for (int backend = 0; backend < mImpl.mBackends.length; backend++) {
            for (int gm = 0; gm < mImpl.mGMs.length; gm++, testIndex++) {
                Description desc = mTests[testIndex];
                String name = desc.getMethodName();
                if (mShouldSkipTest[testIndex]) {
                    continue;
                }
                ++testNumber;
                notifier.fireTestStarted(desc);
                long value = java.lang.Long.MAX_VALUE;
                String error = null;
                try {
                    value = mImpl.nExecuteGM(gm, backend);
                } catch (SkQPException exept) {
                    error = exept.getMessage();
                }
                String result = "pass";
                if (error != null) {
                    SkQPRunner.Fail(desc, notifier, String.format("Exception: %s", error));
                    Log.w(TAG, String.format("[ERROR] '%s': %s", name, error));
                    result = "ERROR";
                } else if (value != 0) {
                    SkQPRunner.Fail(desc, notifier, String.format(
                                "Image mismatch: max channel diff = %d", value));
                    Log.w(TAG, String.format("[FAIL] '%s': %d > 0", name, value));
                    result = "FAIL";
                }
                notifier.fireTestFinished(desc);
                Log.i(TAG, String.format("Rendering Test '%s' complete (%d/%d). [%s]",
                                         name, testNumber, mShouldRunTestCount, result));
            }
        }
        for (int unitTest = 0; unitTest < mImpl.mUnitTests.length; unitTest++, testIndex++) {
            Description desc = mTests[testIndex];
            String name = desc.getMethodName();
            if (mShouldSkipTest[testIndex]) {
                continue;
            }
            ++testNumber;
            notifier.fireTestStarted(desc);
            String[] errors = mImpl.nExecuteUnitTest(unitTest);
            String result = "pass";
            if (errors != null && errors.length > 0) {
                Log.w(TAG, String.format("[FAIL] Test '%s' had %d failures.", name, errors.length));
                for (String error : errors) {
                    SkQPRunner.Fail(desc, notifier, error);
                    Log.w(TAG, String.format("[FAIL] '%s': %s", name, error));
                }
                result = "FAIL";
            }
            notifier.fireTestFinished(desc);
            Log.i(TAG, String.format("Test '%s' complete (%d/%d). [%s]",
                                     name, testNumber, mShouldRunTestCount, result));
        }
        mImpl.nMakeReport();
        Log.i(TAG, String.format("output written to \"%s\"", mOutputDirectory));
    }
}
