/*
 * 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 com.android.server.notification;

import android.app.AlarmManager;
import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.net.Uri;
import android.service.notification.Condition;
import android.service.notification.IConditionProvider;
import android.service.notification.ZenModeConfig;
import android.text.format.DateUtils;
import android.util.Log;
import android.util.Slog;

import com.android.server.notification.NotificationManagerService.DumpFilter;

import java.io.PrintWriter;

/** Built-in zen condition provider for simple time-based conditions */
public class CountdownConditionProvider extends SystemConditionProviderService {
    private static final String TAG = "ConditionProviders.CCP";
    private static final boolean DEBUG = Log.isLoggable("ConditionProviders", Log.DEBUG);

    public static final ComponentName COMPONENT =
            new ComponentName("android", CountdownConditionProvider.class.getName());

    private static final String ACTION = CountdownConditionProvider.class.getName();
    private static final int REQUEST_CODE = 100;
    private static final String EXTRA_CONDITION_ID = "condition_id";

    private final Context mContext = this;
    private final Receiver mReceiver = new Receiver();

    private boolean mConnected;
    private long mTime;
    private boolean mIsAlarm;

    public CountdownConditionProvider() {
        if (DEBUG) Slog.d(TAG, "new CountdownConditionProvider()");
    }

    @Override
    public ComponentName getComponent() {
        return COMPONENT;
    }

    @Override
    public boolean isValidConditionId(Uri id) {
        return ZenModeConfig.isValidCountdownConditionId(id);
    }

    @Override
    public void attachBase(Context base) {
        attachBaseContext(base);
    }

    @Override
    public void onBootComplete() {
        // noop
    }

    @Override
    public IConditionProvider asInterface() {
        return (IConditionProvider) onBind(null);
    }

    @Override
    public void dump(PrintWriter pw, DumpFilter filter) {
        pw.println("    CountdownConditionProvider:");
        pw.print("      mConnected="); pw.println(mConnected);
        pw.print("      mTime="); pw.println(mTime);
    }

    @Override
    public void onConnected() {
        if (DEBUG) Slog.d(TAG, "onConnected");
        mContext.registerReceiver(mReceiver, new IntentFilter(ACTION));
        mConnected = true;
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        if (DEBUG) Slog.d(TAG, "onDestroy");
        if (mConnected) {
            mContext.unregisterReceiver(mReceiver);
        }
        mConnected = false;
    }

    @Override
    public void onSubscribe(Uri conditionId) {
        if (DEBUG) Slog.d(TAG, "onSubscribe " + conditionId);
        mTime = ZenModeConfig.tryParseCountdownConditionId(conditionId);
        mIsAlarm = ZenModeConfig.isValidCountdownToAlarmConditionId(conditionId);
        final AlarmManager alarms = (AlarmManager)
                mContext.getSystemService(Context.ALARM_SERVICE);
        final Intent intent = new Intent(ACTION)
                .putExtra(EXTRA_CONDITION_ID, conditionId)
                .setFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
        final PendingIntent pendingIntent = PendingIntent.getBroadcast(mContext, REQUEST_CODE,
                intent, PendingIntent.FLAG_UPDATE_CURRENT);
        alarms.cancel(pendingIntent);
        if (mTime > 0) {
            final long now = System.currentTimeMillis();
            final CharSequence span =
                    DateUtils.getRelativeTimeSpanString(mTime, now, DateUtils.MINUTE_IN_MILLIS);
            if (mTime <= now) {
                // in the past, already false
                notifyCondition(newCondition(mTime, mIsAlarm, Condition.STATE_FALSE));
            } else {
                // in the future, set an alarm
                alarms.setExact(AlarmManager.RTC_WAKEUP, mTime, pendingIntent);
            }
            if (DEBUG) Slog.d(TAG, String.format(
                    "%s %s for %s, %s in the future (%s), now=%s",
                    (mTime <= now ? "Not scheduling" : "Scheduling"),
                    ACTION, ts(mTime), mTime - now, span, ts(now)));
        }
    }

    @Override
    public void onUnsubscribe(Uri conditionId) {
        // noop
    }

    private final class Receiver extends BroadcastReceiver {
        @Override
        public void onReceive(Context context, Intent intent) {
            if (ACTION.equals(intent.getAction())) {
                final Uri conditionId = intent.getParcelableExtra(EXTRA_CONDITION_ID);
                final boolean alarm = ZenModeConfig.isValidCountdownToAlarmConditionId(conditionId);
                final long time = ZenModeConfig.tryParseCountdownConditionId(conditionId);
                if (DEBUG) Slog.d(TAG, "Countdown condition fired: " + conditionId);
                if (time > 0) {
                    notifyCondition(newCondition(time, alarm, Condition.STATE_FALSE));
                }
            }
        }
    }

    private static final Condition newCondition(long time, boolean alarm, int state) {
        return new Condition(ZenModeConfig.toCountdownConditionId(time, alarm),
                "", "", "", 0, state,Condition.FLAG_RELEVANT_NOW);
    }

    public static String tryParseDescription(Uri conditionUri) {
        final long time = ZenModeConfig.tryParseCountdownConditionId(conditionUri);
        if (time == 0) return null;
        final long now = System.currentTimeMillis();
        final CharSequence span =
                DateUtils.getRelativeTimeSpanString(time, now, DateUtils.MINUTE_IN_MILLIS);
        return String.format("Scheduled for %s, %s in the future (%s), now=%s",
                ts(time), time - now, span, ts(now));
    }

}
