/*
 * Copyright (C) 2017 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.job.controllers;

import static com.android.server.job.JobSchedulerService.sElapsedRealtimeClock;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.UserHandle;
import android.util.ArraySet;
import android.util.Slog;

import com.android.internal.annotations.VisibleForTesting;
import com.android.server.job.JobSchedulerService;
import com.android.server.job.StateChangedListener;
import com.android.server.storage.DeviceStorageMonitorService;

import java.io.PrintWriter;

/**
 * Simple controller that tracks the status of the device's storage.
 */
public final class StorageController extends StateController {
    private static final String TAG = "JobScheduler.Stor";

    private static final Object sCreationLock = new Object();
    private static volatile StorageController sController;

    private final ArraySet<JobStatus> mTrackedTasks = new ArraySet<JobStatus>();
    private StorageTracker mStorageTracker;

    public static StorageController get(JobSchedulerService taskManagerService) {
        synchronized (sCreationLock) {
            if (sController == null) {
                sController = new StorageController(taskManagerService,
                        taskManagerService.getContext(), taskManagerService.getLock());
            }
        }
        return sController;
    }

    @VisibleForTesting
    public StorageTracker getTracker() {
        return mStorageTracker;
    }

    @VisibleForTesting
    public static StorageController getForTesting(StateChangedListener stateChangedListener,
            Context context) {
        return new StorageController(stateChangedListener, context, new Object());
    }

    private StorageController(StateChangedListener stateChangedListener, Context context,
            Object lock) {
        super(stateChangedListener, context, lock);
        mStorageTracker = new StorageTracker();
        mStorageTracker.startTracking();
    }

    @Override
    public void maybeStartTrackingJobLocked(JobStatus taskStatus, JobStatus lastJob) {
        if (taskStatus.hasStorageNotLowConstraint()) {
            mTrackedTasks.add(taskStatus);
            taskStatus.setTrackingController(JobStatus.TRACKING_STORAGE);
            taskStatus.setStorageNotLowConstraintSatisfied(mStorageTracker.isStorageNotLow());
        }
    }

    @Override
    public void maybeStopTrackingJobLocked(JobStatus taskStatus, JobStatus incomingJob,
            boolean forUpdate) {
        if (taskStatus.clearTrackingController(JobStatus.TRACKING_STORAGE)) {
            mTrackedTasks.remove(taskStatus);
        }
    }

    private void maybeReportNewStorageState() {
        final boolean storageNotLow = mStorageTracker.isStorageNotLow();
        boolean reportChange = false;
        synchronized (mLock) {
            for (int i = mTrackedTasks.size() - 1; i >= 0; i--) {
                final JobStatus ts = mTrackedTasks.valueAt(i);
                boolean previous = ts.setStorageNotLowConstraintSatisfied(storageNotLow);
                if (previous != storageNotLow) {
                    reportChange = true;
                }
            }
        }
        // Let the scheduler know that state has changed. This may or may not result in an
        // execution.
        if (reportChange) {
            mStateChangedListener.onControllerStateChanged();
        }
        // Also tell the scheduler that any ready jobs should be flushed.
        if (storageNotLow) {
            mStateChangedListener.onRunJobNow(null);
        }
    }

    public final class StorageTracker extends BroadcastReceiver {
        /**
         * Track whether storage is low.
         */
        private boolean mStorageLow;
        /** Sequence number of last broadcast. */
        private int mLastBatterySeq = -1;

        public StorageTracker() {
        }

        public void startTracking() {
            IntentFilter filter = new IntentFilter();

            // Storage status.  Just need to register, since STORAGE_LOW is a sticky
            // broadcast we will receive that if it is currently active.
            filter.addAction(Intent.ACTION_DEVICE_STORAGE_LOW);
            filter.addAction(Intent.ACTION_DEVICE_STORAGE_OK);
            mContext.registerReceiver(this, filter);
        }

        public boolean isStorageNotLow() {
            return !mStorageLow;
        }

        public int getSeq() {
            return mLastBatterySeq;
        }

        @Override
        public void onReceive(Context context, Intent intent) {
            onReceiveInternal(intent);
        }

        @VisibleForTesting
        public void onReceiveInternal(Intent intent) {
            final String action = intent.getAction();
            mLastBatterySeq = intent.getIntExtra(DeviceStorageMonitorService.EXTRA_SEQUENCE,
                    mLastBatterySeq);
            if (Intent.ACTION_DEVICE_STORAGE_LOW.equals(action)) {
                if (DEBUG) {
                    Slog.d(TAG, "Available storage too low to do work. @ "
                            + sElapsedRealtimeClock.millis());
                }
                mStorageLow = true;
            } else if (Intent.ACTION_DEVICE_STORAGE_OK.equals(action)) {
                if (DEBUG) {
                    Slog.d(TAG, "Available stoage high enough to do work. @ "
                            + sElapsedRealtimeClock.millis());
                }
                mStorageLow = false;
                maybeReportNewStorageState();
            }
        }
    }

    @Override
    public void dumpControllerStateLocked(PrintWriter pw, int filterUid) {
        pw.print("Storage: not low = ");
        pw.print(mStorageTracker.isStorageNotLow());
        pw.print(", seq=");
        pw.println(mStorageTracker.getSeq());
        pw.print("Tracking ");
        pw.print(mTrackedTasks.size());
        pw.println(":");
        for (int i = 0; i < mTrackedTasks.size(); i++) {
            final JobStatus js = mTrackedTasks.valueAt(i);
            if (!js.shouldDump(filterUid)) {
                continue;
            }
            pw.print("  #");
            js.printUniqueId(pw);
            pw.print(" from ");
            UserHandle.formatUid(pw, js.getSourceUid());
            pw.println();
        }
    }
}
