/*
 * 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.settings.applications.appinfo;

import android.app.LoaderManager;
import android.content.Context;
import android.content.Loader;
import android.net.INetworkStatsService;
import android.net.INetworkStatsSession;
import android.net.NetworkTemplate;
import android.os.Bundle;
import android.os.RemoteException;
import android.os.ServiceManager;
import android.support.annotation.VisibleForTesting;
import android.support.v7.preference.Preference;
import android.support.v7.preference.PreferenceScreen;
import android.text.format.DateUtils;
import android.text.format.Formatter;

import com.android.settings.R;
import com.android.settings.SettingsPreferenceFragment;
import com.android.settings.Utils;
import com.android.settings.applications.AppInfoDashboardFragment;
import com.android.settings.datausage.AppDataUsage;
import com.android.settings.datausage.DataUsageList;
import com.android.settings.datausage.DataUsageUtils;
import com.android.settingslib.AppItem;
import com.android.settingslib.core.lifecycle.Lifecycle;
import com.android.settingslib.core.lifecycle.LifecycleObserver;
import com.android.settingslib.core.lifecycle.events.OnPause;
import com.android.settingslib.core.lifecycle.events.OnResume;
import com.android.settingslib.net.ChartData;
import com.android.settingslib.net.ChartDataLoader;

public class AppDataUsagePreferenceController extends AppInfoPreferenceControllerBase
        implements LoaderManager.LoaderCallbacks<ChartData>, LifecycleObserver, OnResume, OnPause {

    private static final String KEY_DATA = "data_settings";
    private ChartData mChartData;
    private INetworkStatsSession mStatsSession;

    public AppDataUsagePreferenceController(Context context, AppInfoDashboardFragment parent,
            Lifecycle lifecycle) {
        super(context, parent, KEY_DATA);
        if (lifecycle != null) {
            lifecycle.addObserver(this);
        }
    }

    @Override
    public int getAvailabilityStatus() {
        return isBandwidthControlEnabled() ? AVAILABLE : DISABLED_UNSUPPORTED;
    }

    @Override
    public void displayPreference(PreferenceScreen screen) {
        super.displayPreference(screen);
        if (isAvailable()) {
            final INetworkStatsService statsService = INetworkStatsService.Stub.asInterface(
                    ServiceManager.getService(Context.NETWORK_STATS_SERVICE));
            try {
                mStatsSession = statsService.openSession();
            } catch (RemoteException e) {
                throw new RuntimeException(e);
            }
        }
    }

    @Override
    public void updateState(Preference preference) {
        preference.setSummary(getDataSummary());
    }

    @Override
    public void onResume() {
        if (mStatsSession != null) {
            final int uid = mParent.getAppEntry().info.uid;
            final AppItem app = new AppItem(uid);
            app.addUid(uid);
            mParent.getLoaderManager().restartLoader(mParent.LOADER_CHART_DATA,
                    ChartDataLoader.buildArgs(getTemplate(mContext), app),
                    this);
        }
    }

    @Override
    public void onPause() {
        mParent.getLoaderManager().destroyLoader(mParent.LOADER_CHART_DATA);
    }

    @Override
    public Loader<ChartData> onCreateLoader(int id, Bundle args) {
        return new ChartDataLoader(mContext, mStatsSession, args);
    }

    @Override
    public void onLoadFinished(Loader<ChartData> loader, ChartData data) {
        mChartData = data;
        updateState(mPreference);
    }

    @Override
    public void onLoaderReset(Loader<ChartData> loader) {
        // Leave last result.
    }

    @Override
    protected Class<? extends SettingsPreferenceFragment> getDetailFragmentClass() {
        return AppDataUsage.class;
    }

    private CharSequence getDataSummary() {
        if (mChartData != null) {
            final long totalBytes = mChartData.detail.getTotalBytes();
            if (totalBytes == 0) {
                return mContext.getString(R.string.no_data_usage);
            }
            return mContext.getString(R.string.data_summary_format,
                    Formatter.formatFileSize(mContext, totalBytes),
                    DateUtils.formatDateTime(mContext, mChartData.detail.getStart(),
                            DateUtils.FORMAT_SHOW_DATE | DateUtils.FORMAT_ABBREV_MONTH));
        }
        return mContext.getString(R.string.computing_size);
    }

    private static NetworkTemplate getTemplate(Context context) {
        if (DataUsageList.hasReadyMobileRadio(context)) {
            return NetworkTemplate.buildTemplateMobileWildcard();
        }
        if (DataUsageUtils.hasWifiRadio(context)) {
            return NetworkTemplate.buildTemplateWifiWildcard();
        }
        return NetworkTemplate.buildTemplateEthernet();
    }

    @VisibleForTesting
    boolean isBandwidthControlEnabled() {
        return Utils.isBandwidthControlEnabled();
    }

}
