/*
 * 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.cellbroadcastreceiver;

import android.content.Context;
import android.os.PersistableBundle;
import android.telephony.CarrierConfigManager;
import android.util.Log;
import android.util.SparseArray;

import com.android.cellbroadcastreceiver.CellBroadcastAlertAudio.ToneType;

import java.util.ArrayList;

/**
 * CellBroadcastOtherChannelsManager handles the additional cell broadcast channels that
 * carriers might enable through carrier config app.
 * Syntax: "<channel id range>:type=<tone type>"
 * For example,
 * <string-array name="carrier_additional_cbs_channels_strings" num="3">
 *     <item value="43008:type=earthquake" />
 *     <item value="0xAFEE:type=tsunami" />
 *     <item value="0xAC00-0xAFED:type=other" />
 *     <item value="1234-5678" />
 * </string-array>
 * If no tones are specified, the tone type will be set to CMAS_DEFAULT.
 */
public class CellBroadcastOtherChannelsManager {

    private static final String TAG = "CellBroadcastChannelsManager";

    private static CellBroadcastOtherChannelsManager sInstance = null;

    /**
     * Channel range caches with sub id as the key.
     */
    private static SparseArray<ArrayList<CellBroadcastChannelRange>> sChannelRanges =
            new SparseArray<>();

    /**
     * Cell broadcast channel range
     * A range is consisted by starting channel id, ending channel id, and the tone type
     */
    public static class CellBroadcastChannelRange {
        public int mStartId;
        public int mEndId;
        public ToneType mToneType;

        public CellBroadcastChannelRange(String channelRange) throws Exception {

            mToneType = ToneType.CMAS_DEFAULT;

            int colonIndex = channelRange.indexOf(':');
            if (colonIndex != -1){
                // Parse the tone type
                String[] tokens = channelRange.substring(colonIndex + 1).trim().split("=");
                if (tokens.length == 2 && tokens[0].trim().equalsIgnoreCase("type")) {
                    mToneType = ToneType.valueOf(tokens[1].trim().toUpperCase());
                }
                channelRange = channelRange.substring(0, colonIndex).trim();
            }

            // Parse the channel range
            int dashIndex = channelRange.indexOf('-');
            if (dashIndex != -1) {
                // range that has start id and end id
                mStartId = Integer.decode(channelRange.substring(0, dashIndex).trim());
                mEndId = Integer.decode(channelRange.substring(dashIndex + 1).trim());
            } else {
                // Not a range, only a single id
                mStartId = mEndId = Integer.decode(channelRange);
            }
        }
    }

    /**
     * Get the instance of the cell broadcast other channel manager
     * @return The singleton instance
     */
    public static CellBroadcastOtherChannelsManager getInstance() {
        if (sInstance == null) {
            sInstance = new CellBroadcastOtherChannelsManager();
        }
        return sInstance;
    }

    /**
     * Get cell broadcast channels enabled by the carriers.
     * @param context Application context
     * @param subId Subscription id
     * @return The list of channel ranges enabled by the carriers.
     */
     public ArrayList<CellBroadcastChannelRange> getCellBroadcastChannelRanges(
            Context context, int subId) {

        // Check if the cache already had it.
        if (sChannelRanges.get(subId) == null) {

            ArrayList<CellBroadcastChannelRange> result = new ArrayList<>();
            String[] ranges;
            CarrierConfigManager configManager =
                    (CarrierConfigManager) context.getSystemService(Context.CARRIER_CONFIG_SERVICE);

            if (configManager != null) {
                PersistableBundle carrierConfig = configManager.getConfig(subId);

                if (carrierConfig != null) {
                    ranges = carrierConfig.getStringArray(
                            CarrierConfigManager.KEY_CARRIER_ADDITIONAL_CBS_CHANNELS_STRINGS);

                    if (ranges == null || ranges.length == 0) {
                        log("No additional channels configured.");

                        // If there is nothing configured, store an empty list in the cache
                        // so we won't look up again next time.
                        sChannelRanges.put(subId, result);
                        return result;
                    }

                    for (String range : ranges) {
                        try {
                            result.add(new CellBroadcastChannelRange(range));
                        } catch (Exception e) {
                            loge("Failed to parse \"" + range + "\". e=" + e);
                        }
                    }

                    sChannelRanges.put(subId, result);

                } else {
                    loge("Can't get carrier config. subId=" + subId);
                    return null;
                }
            } else {
                loge("Carrier config manager is not available");
                return null;
            }
        }

        return sChannelRanges.get(subId);
    }

    private static void log(String msg) {
        Log.d(TAG, msg);
    }

    private static void loge(String msg) {
        Log.e(TAG, msg);
    }
}
