/*
 * 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.reporting.ISensorTestNode;
import android.os.PowerManager;
import android.os.PowerManager.WakeLock;

import java.util.concurrent.TimeUnit;

/**
 * An {@link SensorOperation} which performs another {@link SensorOperation} 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 SensorOperation {
    private static final String ACTION = "AlarmOperationAction";
    private static final String WAKE_LOCK_TAG = "AlarmOperationWakeLock";

    private final SensorOperation 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 SensorOperation} 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(
            SensorOperation operation,
            Context context,
            long sleepDuration,
            TimeUnit timeUnit) {
        super(operation.getStats());
        mOperation = operation;
        mContext = context;
        mSleepDuration = sleepDuration;
        mTimeUnit = timeUnit;
    }

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

        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, PendingIntent.FLAG_MUTABLE_UNAUDITED);
        am.setExact(AlarmManager.RTC_WAKEUP, wakeupTimeMs, pendingIntent);

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

    /**
     * {@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 || 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;
    }
}
