/*
 * Copyright (C) 2018 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.settingslib.utils;

import android.content.Context;
import android.icu.text.DateFormat;
import android.icu.text.MeasureFormat;
import android.icu.text.MeasureFormat.FormatWidth;
import android.icu.util.Measure;
import android.icu.util.MeasureUnit;
import android.text.TextUtils;

import androidx.annotation.Nullable;

import com.android.settingslib.R;

import java.time.Instant;
import java.util.Date;
import java.util.Locale;
import java.util.concurrent.TimeUnit;

/** Utility class for keeping power related strings consistent**/
public class PowerUtil {

    private static final long SEVEN_MINUTES_MILLIS = TimeUnit.MINUTES.toMillis(7);
    private static final long FIFTEEN_MINUTES_MILLIS = TimeUnit.MINUTES.toMillis(15);
    private static final long ONE_DAY_MILLIS = TimeUnit.DAYS.toMillis(1);
    private static final long TWO_DAYS_MILLIS = TimeUnit.DAYS.toMillis(2);
    private static final long ONE_HOUR_MILLIS = TimeUnit.HOURS.toMillis(1);

    /**
     * This method produces the text used in various places throughout the system to describe the
     * remaining battery life of the phone in a consistent manner.
     *
     * @param context
     * @param drainTimeMs The estimated time remaining before the phone dies in milliseconds.
     * @param percentageString An optional percentage of battery remaining string.
     * @param basedOnUsage Whether this estimate is based on usage or simple extrapolation.
     * @return a properly formatted and localized string describing how much time remains
     * before the battery runs out.
     */
    public static String getBatteryRemainingStringFormatted(Context context, long drainTimeMs,
            @Nullable String percentageString, boolean basedOnUsage) {
        if (drainTimeMs > 0) {
            if (drainTimeMs <= SEVEN_MINUTES_MILLIS) {
                // show a imminent shutdown warning if less than 7 minutes remain
                return getShutdownImminentString(context, percentageString);
            } else if (drainTimeMs <= FIFTEEN_MINUTES_MILLIS) {
                // show a less than 15 min remaining warning if appropriate
                CharSequence timeString = StringUtil.formatElapsedTime(context,
                        FIFTEEN_MINUTES_MILLIS,
                        false /* withSeconds */);
                return getUnderFifteenString(context, timeString, percentageString);
            } else if (drainTimeMs >= TWO_DAYS_MILLIS) {
                // just say more than two day if over 48 hours
                return getMoreThanTwoDaysString(context, percentageString);
            } else if (drainTimeMs >= ONE_DAY_MILLIS) {
                // show remaining days & hours if more than a day
                return getMoreThanOneDayString(context, drainTimeMs,
                        percentageString, basedOnUsage);
            } else {
                // show the time of day we think you'll run out
                return getRegularTimeRemainingString(context, drainTimeMs,
                        percentageString, basedOnUsage);
            }
        }
        return null;
    }

    /**
     * Method to produce a shortened string describing the remaining battery. Suitable for Quick
     * Settings and other areas where space is constrained.
     *
     * @param context context to fetch descriptions from
     * @param drainTimeMs The estimated time remaining before the phone dies in milliseconds.
     *
     * @return a properly formatted and localized short string describing how much time remains
     * before the battery runs out.
     */
    @Nullable
    public static String getBatteryRemainingShortStringFormatted(
            Context context, long drainTimeMs) {
        if (drainTimeMs <= 0) {
            return null;
        }

        if (drainTimeMs <= ONE_DAY_MILLIS) {
            return getRegularTimeRemainingShortString(context, drainTimeMs);
        } else {
            return getMoreThanOneDayShortString(context, drainTimeMs);
        }
    }

    private static String getShutdownImminentString(Context context, String percentageString) {
        return TextUtils.isEmpty(percentageString)
                ? context.getString(R.string.power_remaining_duration_only_shutdown_imminent)
                : context.getString(
                        R.string.power_remaining_duration_shutdown_imminent,
                        percentageString);
    }

    private static String getUnderFifteenString(Context context, CharSequence timeString,
            String percentageString) {
        return TextUtils.isEmpty(percentageString)
                ? context.getString(R.string.power_remaining_less_than_duration_only, timeString)
                : context.getString(
                        R.string.power_remaining_less_than_duration,
                        timeString,
                        percentageString);

    }

    private static String getMoreThanOneDayString(Context context, long drainTimeMs,
            String percentageString, boolean basedOnUsage) {
        final long roundedTimeMs = roundTimeToNearestThreshold(drainTimeMs, ONE_HOUR_MILLIS);
        CharSequence timeString = StringUtil.formatElapsedTime(context,
                roundedTimeMs,
                false /* withSeconds */);

        if (TextUtils.isEmpty(percentageString)) {
            int id = basedOnUsage
                    ? R.string.power_remaining_duration_only_enhanced
                    : R.string.power_remaining_duration_only;
            return context.getString(id, timeString);
        } else {
            int id = basedOnUsage
                    ? R.string.power_discharging_duration_enhanced
                    : R.string.power_discharging_duration;
            return context.getString(id, timeString, percentageString);
        }
    }

    private static String getMoreThanOneDayShortString(Context context, long drainTimeMs) {
        final long roundedTimeMs = roundTimeToNearestThreshold(drainTimeMs, ONE_HOUR_MILLIS);
        CharSequence timeString = StringUtil.formatElapsedTime(context, roundedTimeMs,
                false /* withSeconds */);

        return context.getString(R.string.power_remaining_duration_only_short, timeString);
    }

    private static String getMoreThanTwoDaysString(Context context, String percentageString) {
        final Locale currentLocale = context.getResources().getConfiguration().getLocales().get(0);
        final MeasureFormat frmt = MeasureFormat.getInstance(currentLocale, FormatWidth.SHORT);

        final Measure daysMeasure = new Measure(2, MeasureUnit.DAY);

        return TextUtils.isEmpty(percentageString)
                ? context.getString(R.string.power_remaining_only_more_than_subtext,
                        frmt.formatMeasures(daysMeasure))
                : context.getString(
                        R.string.power_remaining_more_than_subtext,
                        frmt.formatMeasures(daysMeasure),
                        percentageString);
    }

    private static String getRegularTimeRemainingString(Context context, long drainTimeMs,
            String percentageString, boolean basedOnUsage) {
        // Get the time of day we think device will die rounded to the nearest 15 min.
        final long roundedTimeOfDayMs =
                roundTimeToNearestThreshold(
                        System.currentTimeMillis() + drainTimeMs,
                        FIFTEEN_MINUTES_MILLIS);

        // convert the time to a properly formatted string.
        String skeleton = android.text.format.DateFormat.getTimeFormatString(context);
        DateFormat fmt = DateFormat.getInstanceForSkeleton(skeleton);
        Date date = Date.from(Instant.ofEpochMilli(roundedTimeOfDayMs));
        CharSequence timeString = fmt.format(date);

        if (TextUtils.isEmpty(percentageString)) {
            int id = basedOnUsage
                    ? R.string.power_discharge_by_only_enhanced
                    : R.string.power_discharge_by_only;
            return context.getString(id, timeString);
        } else {
            int id = basedOnUsage
                    ? R.string.power_discharge_by_enhanced
                    : R.string.power_discharge_by;
            return context.getString(id, timeString, percentageString);
        }
    }

    private static String getRegularTimeRemainingShortString(Context context, long drainTimeMs) {
        // Get the time of day we think device will die rounded to the nearest 15 min.
        final long roundedTimeOfDayMs =
                roundTimeToNearestThreshold(
                        System.currentTimeMillis() + drainTimeMs,
                        FIFTEEN_MINUTES_MILLIS);

        // convert the time to a properly formatted string.
        String skeleton = android.text.format.DateFormat.getTimeFormatString(context);
        DateFormat fmt = DateFormat.getInstanceForSkeleton(skeleton);
        Date date = Date.from(Instant.ofEpochMilli(roundedTimeOfDayMs));
        CharSequence timeString = fmt.format(date);

        return context.getString(R.string.power_discharge_by_only_short, timeString);
    }

    public static long convertUsToMs(long timeUs) {
        return timeUs / 1000;
    }

    public static long convertMsToUs(long timeMs) {
        return timeMs * 1000;
    }

    /**
     * Rounds a time to the nearest multiple of the provided threshold. Note: This function takes
     * the absolute value of the inputs since it is only meant to be used for times, not general
     * purpose rounding.
     *
     * ex: roundTimeToNearestThreshold(41, 24) = 48
     * @param drainTime The amount to round
     * @param threshold The value to round to a multiple of
     * @return The rounded value as a long
     */
    public static long roundTimeToNearestThreshold(long drainTime, long threshold) {
        long time = Math.abs(drainTime);
        long multiple = Math.abs(threshold);
        final long remainder = time % multiple;
        if (remainder < multiple / 2) {
            return time - remainder;
        } else {
            return time - remainder + multiple;
        }
    }
}
