/*
 * 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.hardware.cts.helpers.sensoroperations;

import android.app.AlarmManager;
import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.hardware.cts.helpers.SensorStats;
import android.os.PowerManager;
import android.os.PowerManager.WakeLock;

import java.util.concurrent.TimeUnit;

/**
 * An {@link ISensorOperation} which performs another {@link ISensorOperation} and then wakes up
 * after a specified period of time and waits for the child operation to complete.
 * <p>
 * This operation can be used to allow the device to go to sleep and wake it up after a specified
 * period of time. After the device wakes up, this operation will hold a wake lock until the child
 * operation finishes. This operation will not force the device into suspend, so if another
 * operation is holding a wake lock, the device will stay awake.  Also, if the child operation
 * finishes before the specified period, this operation return when the child operation finishes
 * but wake the device one time at the specified period.
 * </p>
 */
public class AlarmOperation extends AbstractSensorOperation {
    private static final String ACTION = "AlarmOperationAction";
    private static final String WAKE_LOCK_TAG = "AlarmOperationWakeLock";

    private final ISensorOperation mOperation;
    private final Context mContext;
    private final long mSleepDuration;
    private final TimeUnit mTimeUnit;

    private boolean mCompleted = false;
    private WakeLock mWakeLock = null;

    /**
     * Constructor for {@link DelaySensorOperation}
     *
     * @param operation the child {@link ISensorOperation} to perform after the delay
     * @param context the context used to access the alarm manager
     * @param sleepDuration the amount of time to sleep
     * @param timeUnit the unit of the duration
     */
    public AlarmOperation(ISensorOperation operation, Context context, long sleepDuration,
            TimeUnit timeUnit) {
        mOperation = operation;
        mContext = context;
        mSleepDuration = sleepDuration;
        mTimeUnit = timeUnit;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void execute() throws InterruptedException {
        // Start alarm
        IntentFilter intentFilter = new IntentFilter(ACTION);
        BroadcastReceiver receiver = new BroadcastReceiver() {
            @Override
            public void onReceive(Context context, Intent intent) {
                acquireWakeLock();
            }
        };
        mContext.registerReceiver(receiver, intentFilter);

        AlarmManager am = (AlarmManager) mContext.getSystemService(Context.ALARM_SERVICE);
        long wakeupTimeMs = (System.currentTimeMillis()
                + TimeUnit.MILLISECONDS.convert(mSleepDuration, mTimeUnit));
        Intent intent = new Intent(ACTION);
        PendingIntent pendingIntent = PendingIntent.getBroadcast(mContext, 0, intent, 0);
        am.setExact(AlarmManager.RTC_WAKEUP, wakeupTimeMs, pendingIntent);

        // Execute operation
        try {
            mOperation.execute();
        } finally {
            releaseWakeLock();
        }
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public SensorStats getStats() {
        return mOperation.getStats();
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public AlarmOperation clone() {
        return new AlarmOperation(mOperation, mContext, mSleepDuration, mTimeUnit);
    }

    /**
     * Method that acquires a wake lock if a wake lock has not already been acquired and if the
     * operation has not yet completed.
     */
    private synchronized void acquireWakeLock() {
        // Don't acquire wake lock if the operation has already completed.
        if (mCompleted == true || mWakeLock != null) {
            return;
        }
        PowerManager pm = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE);
        mWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, WAKE_LOCK_TAG);
    }

    /**
     * Method that releases the wake lock if it has been acquired.
     */
    private synchronized void releaseWakeLock() {
        mCompleted = true;
        if (mWakeLock != null) {
            mWakeLock.release();
        }
        mWakeLock = null;
    }
}
