/**
 * 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 android.hardware.radio;

import android.annotation.CallbackExecutor;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.SystemApi;
import android.os.Parcel;
import android.os.Parcelable;

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.concurrent.Executor;
import java.util.stream.Collectors;

/**
 * @hide
 */
@SystemApi
public final class ProgramList implements AutoCloseable {

    private final Object mLock = new Object();
    private final Map<ProgramSelector.Identifier, RadioManager.ProgramInfo> mPrograms =
            new HashMap<>();

    private final List<ListCallback> mListCallbacks = new ArrayList<>();
    private final List<OnCompleteListener> mOnCompleteListeners = new ArrayList<>();
    private OnCloseListener mOnCloseListener;
    private boolean mIsClosed = false;
    private boolean mIsComplete = false;

    ProgramList() {}

    /**
     * Callback for list change operations.
     */
    public abstract static class ListCallback {
        /**
         * Called when item was modified or added to the list.
         */
        public void onItemChanged(@NonNull ProgramSelector.Identifier id) { }

        /**
         * Called when item was removed from the list.
         */
        public void onItemRemoved(@NonNull ProgramSelector.Identifier id) { }
    }

    /**
     * Listener of list complete event.
     */
    public interface OnCompleteListener {
        /**
         * Called when the list turned complete (i.e. when the scan process
         * came to an end).
         */
        void onComplete();
    }

    interface OnCloseListener {
        void onClose();
    }

    /**
     * Registers list change callback with executor.
     */
    public void registerListCallback(@NonNull @CallbackExecutor Executor executor,
            @NonNull ListCallback callback) {
        registerListCallback(new ListCallback() {
            public void onItemChanged(@NonNull ProgramSelector.Identifier id) {
                executor.execute(() -> callback.onItemChanged(id));
            }

            public void onItemRemoved(@NonNull ProgramSelector.Identifier id) {
                executor.execute(() -> callback.onItemRemoved(id));
            }
        });
    }

    /**
     * Registers list change callback.
     */
    public void registerListCallback(@NonNull ListCallback callback) {
        synchronized (mLock) {
            if (mIsClosed) return;
            mListCallbacks.add(Objects.requireNonNull(callback));
        }
    }

    /**
     * Unregisters list change callback.
     */
    public void unregisterListCallback(@NonNull ListCallback callback) {
        synchronized (mLock) {
            if (mIsClosed) return;
            mListCallbacks.remove(Objects.requireNonNull(callback));
        }
    }

    /**
     * Adds list complete event listener with executor.
     */
    public void addOnCompleteListener(@NonNull @CallbackExecutor Executor executor,
            @NonNull OnCompleteListener listener) {
        addOnCompleteListener(() -> executor.execute(listener::onComplete));
    }

    /**
     * Adds list complete event listener.
     */
    public void addOnCompleteListener(@NonNull OnCompleteListener listener) {
        synchronized (mLock) {
            if (mIsClosed) return;
            mOnCompleteListeners.add(Objects.requireNonNull(listener));
            if (mIsComplete) listener.onComplete();
        }
    }

    /**
     * Removes list complete event listener.
     */
    public void removeOnCompleteListener(@NonNull OnCompleteListener listener) {
        synchronized (mLock) {
            if (mIsClosed) return;
            mOnCompleteListeners.remove(Objects.requireNonNull(listener));
        }
    }

    void setOnCloseListener(@Nullable OnCloseListener listener) {
        synchronized (mLock) {
            if (mOnCloseListener != null) {
                throw new IllegalStateException("Close callback is already set");
            }
            mOnCloseListener = listener;
        }
    }

    /**
     * Disables list updates and releases all resources.
     */
    public void close() {
        synchronized (mLock) {
            if (mIsClosed) return;
            mIsClosed = true;
            mPrograms.clear();
            mListCallbacks.clear();
            mOnCompleteListeners.clear();
            if (mOnCloseListener != null) {
                mOnCloseListener.onClose();
                mOnCloseListener = null;
            }
        }
    }

    void apply(@NonNull Chunk chunk) {
        synchronized (mLock) {
            if (mIsClosed) return;

            mIsComplete = false;

            if (chunk.isPurge()) {
                new HashSet<>(mPrograms.keySet()).stream().forEach(id -> removeLocked(id));
            }

            chunk.getRemoved().stream().forEach(id -> removeLocked(id));
            chunk.getModified().stream().forEach(info -> putLocked(info));

            if (chunk.isComplete()) {
                mIsComplete = true;
                mOnCompleteListeners.forEach(cb -> cb.onComplete());
            }
        }
    }

    private void putLocked(@NonNull RadioManager.ProgramInfo value) {
        ProgramSelector.Identifier key = value.getSelector().getPrimaryId();
        mPrograms.put(Objects.requireNonNull(key), value);
        ProgramSelector.Identifier sel = value.getSelector().getPrimaryId();
        mListCallbacks.forEach(cb -> cb.onItemChanged(sel));
    }

    private void removeLocked(@NonNull ProgramSelector.Identifier key) {
        RadioManager.ProgramInfo removed = mPrograms.remove(Objects.requireNonNull(key));
        if (removed == null) return;
        ProgramSelector.Identifier sel = removed.getSelector().getPrimaryId();
        mListCallbacks.forEach(cb -> cb.onItemRemoved(sel));
    }

    /**
     * Converts the program list in its current shape to the static List<>.
     *
     * @return the new List<> object; it won't receive any further updates
     */
    public @NonNull List<RadioManager.ProgramInfo> toList() {
        synchronized (mLock) {
            return mPrograms.values().stream().collect(Collectors.toList());
        }
    }

    /**
     * Returns the program with a specified primary identifier.
     *
     * @param id primary identifier of a program to fetch
     * @return the program info, or null if there is no such program on the list
     */
    public @Nullable RadioManager.ProgramInfo get(@NonNull ProgramSelector.Identifier id) {
        synchronized (mLock) {
            return mPrograms.get(Objects.requireNonNull(id));
        }
    }

    /**
     * Filter for the program list.
     */
    public static final class Filter implements Parcelable {
        private final @NonNull Set<Integer> mIdentifierTypes;
        private final @NonNull Set<ProgramSelector.Identifier> mIdentifiers;
        private final boolean mIncludeCategories;
        private final boolean mExcludeModifications;
        private final @Nullable Map<String, String> mVendorFilter;

        /**
         * Constructor of program list filter.
         *
         * Arrays passed to this constructor become owned by this object, do not modify them later.
         *
         * @param identifierTypes see getIdentifierTypes()
         * @param identifiers see getIdentifiers()
         * @param includeCategories see areCategoriesIncluded()
         * @param excludeModifications see areModificationsExcluded()
         */
        public Filter(@NonNull Set<Integer> identifierTypes,
                @NonNull Set<ProgramSelector.Identifier> identifiers,
                boolean includeCategories, boolean excludeModifications) {
            mIdentifierTypes = Objects.requireNonNull(identifierTypes);
            mIdentifiers = Objects.requireNonNull(identifiers);
            mIncludeCategories = includeCategories;
            mExcludeModifications = excludeModifications;
            mVendorFilter = null;
        }

        /**
         * @hide for framework use only
         */
        public Filter() {
            mIdentifierTypes = Collections.emptySet();
            mIdentifiers = Collections.emptySet();
            mIncludeCategories = false;
            mExcludeModifications = false;
            mVendorFilter = null;
        }

        /**
         * @hide for framework use only
         */
        public Filter(@Nullable Map<String, String> vendorFilter) {
            mIdentifierTypes = Collections.emptySet();
            mIdentifiers = Collections.emptySet();
            mIncludeCategories = false;
            mExcludeModifications = false;
            mVendorFilter = vendorFilter;
        }

        private Filter(@NonNull Parcel in) {
            mIdentifierTypes = Utils.createIntSet(in);
            mIdentifiers = Utils.createSet(in, ProgramSelector.Identifier.CREATOR);
            mIncludeCategories = in.readByte() != 0;
            mExcludeModifications = in.readByte() != 0;
            mVendorFilter = Utils.readStringMap(in);
        }

        @Override
        public void writeToParcel(Parcel dest, int flags) {
            Utils.writeIntSet(dest, mIdentifierTypes);
            Utils.writeSet(dest, mIdentifiers);
            dest.writeByte((byte) (mIncludeCategories ? 1 : 0));
            dest.writeByte((byte) (mExcludeModifications ? 1 : 0));
            Utils.writeStringMap(dest, mVendorFilter);
        }

        @Override
        public int describeContents() {
            return 0;
        }

        public static final @android.annotation.NonNull Parcelable.Creator<Filter> CREATOR = new Parcelable.Creator<Filter>() {
            public Filter createFromParcel(Parcel in) {
                return new Filter(in);
            }

            public Filter[] newArray(int size) {
                return new Filter[size];
            }
        };

        /**
         * @hide for framework use only
         */
        public Map<String, String> getVendorFilter() {
            return mVendorFilter;
        }

        /**
         * Returns the list of identifier types that satisfy the filter.
         *
         * If the program list entry contains at least one identifier of the type
         * listed, it satisfies this condition.
         *
         * Empty list means no filtering on identifier type.
         *
         * @return the list of accepted identifier types, must not be modified
         */
        public @NonNull Set<Integer> getIdentifierTypes() {
            return mIdentifierTypes;
        }

        /**
         * Returns the list of identifiers that satisfy the filter.
         *
         * If the program list entry contains at least one listed identifier,
         * it satisfies this condition.
         *
         * Empty list means no filtering on identifier.
         *
         * @return the list of accepted identifiers, must not be modified
         */
        public @NonNull Set<ProgramSelector.Identifier> getIdentifiers() {
            return mIdentifiers;
        }

        /**
         * Checks, if non-tunable entries that define tree structure on the
         * program list (i.e. DAB ensembles) should be included.
         */
        public boolean areCategoriesIncluded() {
            return mIncludeCategories;
        }

        /**
         * Checks, if updates on entry modifications should be disabled.
         *
         * If true, 'modified' vector of ProgramListChunk must contain list
         * additions only. Once the program is added to the list, it's not
         * updated anymore.
         */
        public boolean areModificationsExcluded() {
            return mExcludeModifications;
        }
    }

    /**
     * @hide This is a transport class used for internal communication between
     *       Broadcast Radio Service and RadioManager.
     *       Do not use it directly.
     */
    public static final class Chunk implements Parcelable {
        private final boolean mPurge;
        private final boolean mComplete;
        private final @NonNull Set<RadioManager.ProgramInfo> mModified;
        private final @NonNull Set<ProgramSelector.Identifier> mRemoved;

        public Chunk(boolean purge, boolean complete,
                @Nullable Set<RadioManager.ProgramInfo> modified,
                @Nullable Set<ProgramSelector.Identifier> removed) {
            mPurge = purge;
            mComplete = complete;
            mModified = (modified != null) ? modified : Collections.emptySet();
            mRemoved = (removed != null) ? removed : Collections.emptySet();
        }

        private Chunk(@NonNull Parcel in) {
            mPurge = in.readByte() != 0;
            mComplete = in.readByte() != 0;
            mModified = Utils.createSet(in, RadioManager.ProgramInfo.CREATOR);
            mRemoved = Utils.createSet(in, ProgramSelector.Identifier.CREATOR);
        }

        @Override
        public void writeToParcel(Parcel dest, int flags) {
            dest.writeByte((byte) (mPurge ? 1 : 0));
            dest.writeByte((byte) (mComplete ? 1 : 0));
            Utils.writeSet(dest, mModified);
            Utils.writeSet(dest, mRemoved);
        }

        @Override
        public int describeContents() {
            return 0;
        }

        public static final @android.annotation.NonNull Parcelable.Creator<Chunk> CREATOR = new Parcelable.Creator<Chunk>() {
            public Chunk createFromParcel(Parcel in) {
                return new Chunk(in);
            }

            public Chunk[] newArray(int size) {
                return new Chunk[size];
            }
        };

        public boolean isPurge() {
            return mPurge;
        }

        public boolean isComplete() {
            return mComplete;
        }

        public @NonNull Set<RadioManager.ProgramInfo> getModified() {
            return mModified;
        }

        public @NonNull Set<ProgramSelector.Identifier> getRemoved() {
            return mRemoved;
        }
    }
}
