/*
 * Copyright (C) 2016 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.datausage;

import android.content.Context;
import android.net.NetworkPolicy;
import android.net.NetworkPolicyManager;
import android.net.NetworkStatsHistory;
import android.text.format.DateUtils;
import android.util.Pair;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;

import com.android.settings.R;
import com.android.settings.Utils;
import com.android.settingslib.net.ChartData;

import libcore.util.Objects;

import java.time.ZonedDateTime;
import java.util.Iterator;

public class CycleAdapter extends ArrayAdapter<CycleAdapter.CycleItem> {

    private final SpinnerInterface mSpinner;
    private final AdapterView.OnItemSelectedListener mListener;

    public CycleAdapter(Context context, SpinnerInterface spinner,
            AdapterView.OnItemSelectedListener listener, boolean isHeader) {
        super(context, isHeader ? R.layout.filter_spinner_item
                : R.layout.data_usage_cycle_item);
        setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
        mSpinner = spinner;
        mListener = listener;
        mSpinner.setAdapter(this);
        mSpinner.setOnItemSelectedListener(mListener);
    }

    /**
     * Find position of {@link CycleItem} in this adapter which is nearest
     * the given {@link CycleItem}.
     */
    public int findNearestPosition(CycleItem target) {
        if (target != null) {
            final int count = getCount();
            for (int i = count - 1; i >= 0; i--) {
                final CycleItem item = getItem(i);
                if (item.compareTo(target) >= 0) {
                    return i;
                }
            }
        }
        return 0;
    }

    /**
     * Rebuild list based on {@link NetworkPolicy} and available
     * {@link NetworkStatsHistory} data. Always selects the newest item,
     * updating the inspection range on chartData.
     */
     public boolean updateCycleList(NetworkPolicy policy, ChartData chartData) {
        // stash away currently selected cycle to try restoring below
        final CycleAdapter.CycleItem previousItem = (CycleAdapter.CycleItem)
                mSpinner.getSelectedItem();
        clear();

        final Context context = getContext();
        NetworkStatsHistory.Entry entry = null;

        long historyStart = Long.MAX_VALUE;
        long historyEnd = Long.MIN_VALUE;
        if (chartData != null) {
            historyStart = chartData.network.getStart();
            historyEnd = chartData.network.getEnd();
        }

        final long now = System.currentTimeMillis();
        if (historyStart == Long.MAX_VALUE) historyStart = now;
        if (historyEnd == Long.MIN_VALUE) historyEnd = now + 1;

        boolean hasCycles = false;
        if (policy != null) {
            final Iterator<Pair<ZonedDateTime, ZonedDateTime>> it = NetworkPolicyManager
                    .cycleIterator(policy);
            while (it.hasNext()) {
                final Pair<ZonedDateTime, ZonedDateTime> cycle = it.next();
                final long cycleStart = cycle.first.toInstant().toEpochMilli();
                final long cycleEnd = cycle.second.toInstant().toEpochMilli();

                final boolean includeCycle;
                if (chartData != null) {
                    entry = chartData.network.getValues(cycleStart, cycleEnd, entry);
                    includeCycle = (entry.rxBytes + entry.txBytes) > 0;
                } else {
                    includeCycle = true;
                }

                if (includeCycle) {
                    add(new CycleAdapter.CycleItem(context, cycleStart, cycleEnd));
                    hasCycles = true;
                }
            }
        }

        if (!hasCycles) {
            // no policy defined cycles; show entry for each four-week period
            long cycleEnd = historyEnd;
            while (cycleEnd > historyStart) {
                final long cycleStart = cycleEnd - (DateUtils.WEEK_IN_MILLIS * 4);

                final boolean includeCycle;
                if (chartData != null) {
                    entry = chartData.network.getValues(cycleStart, cycleEnd, entry);
                    includeCycle = (entry.rxBytes + entry.txBytes) > 0;
                } else {
                    includeCycle = true;
                }

                if (includeCycle) {
                    add(new CycleAdapter.CycleItem(context, cycleStart, cycleEnd));
                }
                cycleEnd = cycleStart;
            }
        }

        // force pick the current cycle (first item)
        if (getCount() > 0) {
            final int position = findNearestPosition(previousItem);
            mSpinner.setSelection(position);

            // only force-update cycle when changed; skipping preserves any
            // user-defined inspection region.
            final CycleAdapter.CycleItem selectedItem = getItem(position);
            if (!Objects.equal(selectedItem, previousItem)) {
                mListener.onItemSelected(null, null, position, 0);
                return false;
            }
        }
        return true;
    }

    /**
     * List item that reflects a specific data usage cycle.
     */
    public static class CycleItem implements Comparable<CycleItem> {
        public CharSequence label;
        public long start;
        public long end;

        public CycleItem(CharSequence label) {
            this.label = label;
        }

        public CycleItem(Context context, long start, long end) {
            this.label = Utils.formatDateRange(context, start, end);
            this.start = start;
            this.end = end;
        }

        @Override
        public String toString() {
            return label.toString();
        }

        @Override
        public boolean equals(Object o) {
            if (o instanceof CycleItem) {
                final CycleItem another = (CycleItem) o;
                return start == another.start && end == another.end;
            }
            return false;
        }

        @Override
        public int compareTo(CycleItem another) {
            return Long.compare(start, another.start);
        }
    }

    public interface SpinnerInterface {
        void setAdapter(CycleAdapter cycleAdapter);
        void setOnItemSelectedListener(AdapterView.OnItemSelectedListener listener);
        Object getSelectedItem();
        void setSelection(int position);
    }
}
