/*
 * Copyright (C) 2014 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 android.support.test.jank;

import android.accessibilityservice.AccessibilityServiceInfo;
import android.app.Instrumentation;
import android.app.UiAutomation;
import android.util.Log;
import android.view.FrameStats;
import android.view.accessibility.AccessibilityWindowInfo;

/** The {@link JankUtil} class provides functionality for monitoring jank. */
public class JankUtil {

    private static final String TAG = JankUtil.class.getSimpleName();

    // Singleton instance
    private static JankUtil sInstance;

    private UiAutomation mUiAutomation;
    private JankMonitor mMonitor;

    /** Private constructor. Clients should use {@link JankUtil#getInstance(Instrumentation)}. */
    private JankUtil(UiAutomation automation) {
        mUiAutomation = automation;

        // Subscribe to window information
        AccessibilityServiceInfo info = mUiAutomation.getServiceInfo();
        info.flags |= AccessibilityServiceInfo.FLAG_RETRIEVE_INTERACTIVE_WINDOWS;
        mUiAutomation.setServiceInfo(info);
    }

    /** Returns a {@link JankUtil} instance. */
    public static JankUtil getInstance(Instrumentation instrumentation) {
        if (sInstance == null) {
            sInstance = new JankUtil(instrumentation.getUiAutomation());
        }
        return sInstance;
    }

    /** Starts monitoring for janky frames of the given {@code type}. */
    public void startMonitor(JankType type) {
        if (mMonitor != null) {
            throw new IllegalStateException("Monitor already started");
        }

        if (type == JankType.CONTENT_FRAMES) {
            mMonitor = new WindowContentJankMonitor();
        } else if (type == JankType.ANIMATION_FRAMES) {
            mMonitor = new WindowAnimationJankMonitor();
        } else {
            throw new RuntimeException("Invalid type");
        }

        mMonitor.clear();
    }

    /** Stops monitoring and returns the {@link JankResult} for this monitoring session. */
    public JankResult stopMonitor() {
        FrameStats stats = mMonitor.getStats();
        mMonitor = null;
        return JankResult.analyze(stats);
    }

    /** Returns the id of the current application window. */
    private int getCurrentWindow() {
        for (AccessibilityWindowInfo window : mUiAutomation.getWindows()) {
            if (window.getType() == AccessibilityWindowInfo.TYPE_APPLICATION) {
                return window.getId();
            }
        }
        throw new RuntimeException("No application window found");
    }

    /** Generic monitoring interface */
    private static interface JankMonitor {
        public void clear();
        public FrameStats getStats();
    }

    /** Monitor for detecting window content frame jank. */
    private class WindowContentJankMonitor implements JankMonitor {
        private int mWindowId = -1;

        @Override
        public void clear() {
            mWindowId = getCurrentWindow();
            mUiAutomation.clearWindowContentFrameStats(mWindowId);
        }

        @Override
        public FrameStats getStats() {
            int currentWindow = getCurrentWindow();
            if (currentWindow != mWindowId) {
                Log.w(TAG, "Current window changed during the test. Did you mean to measure " +
                        "ANIMATION_FRAMES?");
            }
            mWindowId = -1;
            return mUiAutomation.getWindowContentFrameStats(currentWindow);
        }
    }

    /** Monitor for detecting window animation frame jank. */
    private class WindowAnimationJankMonitor implements JankMonitor {
        @Override
        public void clear() {
            mUiAutomation.clearWindowAnimationFrameStats();
        }

        @Override
        public FrameStats getStats() {
            return mUiAutomation.getWindowAnimationFrameStats();
        }
    }
}
