// Copyright 2014 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

package org.chromium.testing.local;

import org.junit.runner.Description;
import org.junit.runner.notification.Failure;

import java.io.PrintStream;
import java.util.Set;

/** Formats and logs test status information in googletest-style. */
public class GtestLogger {

    private final PrintStream mOutputStream;

    public GtestLogger(PrintStream outputStream) {
        mOutputStream = outputStream;
    }

    /** Logs the start of an individual test. */
    public void testStarted(Description test) {
        mOutputStream.format("[ RUN      ] %s.%s", test.getClassName(), test.getMethodName());
        mOutputStream.println();
    }

    /** Logs a test failure. */
    public void testFailed(Failure f) {
        if (f.getException() != null) {
            f.getException().printStackTrace(mOutputStream);
        }
    }

    /** Logs the end of an individual test. */
    public void testFinished(Description test, boolean passed, long elapsedTimeMillis) {
        if (passed) {
            mOutputStream.format(
                    "[       OK ] %s.%s (%d ms)",
                    test.getClassName(), test.getMethodName(), elapsedTimeMillis);
        } else {
            mOutputStream.format(
                    "[   FAILED ] %s.%s (%d ms)",
                    test.getClassName(), test.getMethodName(), elapsedTimeMillis);
        }
        mOutputStream.println();
    }

    /** Logs the start of a test case. */
    public void testCaseStarted(Description test, int testCount) {
        mOutputStream.format(
                "[----------] Run %d test cases from %s", testCount, test.getClassName());
        mOutputStream.println();
    }

    /** Logs the end of a test case. */
    public void testCaseFinished(Description test, int testCount, long elapsedTimeMillis) {
        mOutputStream.format(
                "[----------] Run %d test cases from %s (%d ms)",
                testCount, test.getClassName(), elapsedTimeMillis);
        mOutputStream.println();
        mOutputStream.println();
    }

    /** Logs the start of a test run. */
    public void testRunStarted(int testCount) {
        mOutputStream.format("[==========] Running %d tests.", testCount);
        mOutputStream.println();
        mOutputStream.println("[----------] Global test environment set-up.");
        mOutputStream.println();
    }

    /** Logs the end of a test run. */
    public void testRunFinished(
            int passedTestCount, Set<Description> failedTests, long elapsedTimeMillis) {
        int totalTestCount = passedTestCount + failedTests.size();
        mOutputStream.println("[----------] Global test environment tear-down.");
        mOutputStream.format(
                "[==========] %d tests ran. (%d ms total)", totalTestCount, elapsedTimeMillis);
        mOutputStream.println();
        mOutputStream.format("[  PASSED  ] %d tests.", passedTestCount);
        mOutputStream.println();
        if (!failedTests.isEmpty()) {
            mOutputStream.format("[  FAILED  ] %d tests.", failedTests.size());
            mOutputStream.println();
            for (Description d : failedTests) {
                mOutputStream.format("[  FAILED  ] %s.%s", d.getClassName(), d.getMethodName());
                mOutputStream.println();
            }
            mOutputStream.println();
        }
    }
}
