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

import android.content.Context;
import android.content.res.XmlResourceParser;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.telephony.SubscriptionInfo;
import android.telephony.SubscriptionManager;
import android.telephony.TelephonyManager;
import android.text.TextUtils;

import com.android.internal.telephony.PhoneConstants;
import com.android.internal.telephony.cat.CatLog;
import com.android.internal.telephony.util.TelephonyUtils;
import com.android.internal.telephony.util.XmlUtils;

import java.util.ArrayList;

/**
 * Provides preset label and/or icon in accordance with mcc/mnc
 * conbination of the inserted SIM card for Multi-SIM model.
 */
public class StkMenuConfig {
    private static final String LOG_TAG =
            new Object(){}.getClass().getEnclosingClass().getSimpleName();
    private static final boolean DBG = TelephonyUtils.IS_DEBUGGABLE;

    private static final String XML_OPERATORS_TAG = "operators";
    private static final String XML_OPERATOR_TAG = "operator";

    private static final String XML_MCC_ATTR = "mcc";
    private static final String XML_MNC_ATTR = "mnc";
    private static final String XML_LABEL_ATTR = "label";
    private static final String XML_ICON_ATTR = "icon";
    private static final String RESOURCE_TYPE = "drawable";

    private static final int UNSPECIFIED = -1;

    private static final Config NO_CONFIG = new Config(0, 0, null, null);

    private static final Object sLock = new Object();
    private static StkMenuConfig sInstance;

    private Context mContext;
    private ArrayList<Config> mArray;
    private Config mConfigs[] = null;

    private static class Config {
        public int mcc;
        public int mnc;
        public String label;
        public String icon;

        public Config(int mcc, int mnc, String label, String icon) {
            this.mcc = mcc;
            this.mnc = mnc;
            this.label = label;
            this.icon = icon;
        }
    }

    public static StkMenuConfig getInstance(Context applicationContext) {
        synchronized (sLock) {
            if (sInstance == null) {
                sInstance = new StkMenuConfig();
                sInstance.initialize(applicationContext);
            }
            return sInstance;
        }
    }

    /**
     * Returns a preset label, if exists.
     */
    public String getLabel(int slotId) {
        findConfig(slotId);

        if (DBG) CatLog.d(LOG_TAG, "getLabel: " + mConfigs[slotId].label + ", slot id: " + slotId);
        return mConfigs[slotId].label;
    }

    /**
     * Returns a preset icon, if exists.
     */
    public Bitmap getIcon(int slotId) {
        findConfig(slotId);

        Bitmap bitmap = null;
        if (mConfigs[slotId].icon != null) {
            int resId = mContext.getResources().getIdentifier(mConfigs[slotId].icon,
                    RESOURCE_TYPE, mContext.getPackageName());
            bitmap = resId == UNSPECIFIED ? null :
                    BitmapFactory.decodeResource(mContext.getResources(), resId);
        }
        if (DBG) CatLog.d(LOG_TAG, "getIcon: " + mConfigs[slotId].icon + ", slot id: " + slotId);
        return bitmap;
    }

    private void findConfig(int slotId) {
        SubscriptionManager sm = (SubscriptionManager) mContext.getSystemService(
                Context.TELEPHONY_SUBSCRIPTION_SERVICE);
        SubscriptionInfo info = (sm != null) ? sm.getActiveSubscriptionInfoForSimSlotIndex(slotId)
                : null;
        if (info == null) {
            mConfigs[slotId] = NO_CONFIG;
            return;
        }

        TelephonyManager telephony =
                (TelephonyManager) mContext.getSystemService(Context.TELEPHONY_SERVICE);
        String operator = telephony.getSimOperator(info.getSubscriptionId());
        if (TextUtils.isEmpty(operator) || (operator.length() < 5)) {
            mConfigs[slotId] = NO_CONFIG;
            return;
        }

        int mcc = Integer.parseInt(operator.substring(0, 3));
        int mnc = Integer.parseInt(operator.substring(3));

        if (mConfigs[slotId] != null && mConfigs[slotId].mcc == mcc
                && mConfigs[slotId].mnc == mnc) {
            if (DBG) CatLog.d(LOG_TAG, "Return the cached config, slot id: " + slotId);
            return;
        }

        if (DBG) CatLog.d(LOG_TAG, "Find config and create the cached config, slot id: " + slotId);
        for (Config config : mArray) {
            if ((config.mcc == mcc) && (config.mnc == mnc)) {
                mConfigs[slotId] = config;
                return;
            }
        }

        mConfigs[slotId] = new Config(mcc, mnc, null, null);
    }

    private void initialize(Context context) {
        mContext = context;
        mArray = new ArrayList<Config>();
        mConfigs = new Config[TelephonyManager.from(mContext).getSupportedModemCount()];

        XmlResourceParser parser = mContext.getResources().getXml(R.xml.menu_conf);

        try {
            XmlUtils.beginDocument(parser, XML_OPERATORS_TAG);

            do {
                XmlUtils.nextElement(parser);

                if (!XML_OPERATOR_TAG.equals(parser.getName())) {
                    break;
                }

                int mcc = parser.getAttributeIntValue(null, XML_MCC_ATTR, UNSPECIFIED);
                int mnc = parser.getAttributeIntValue(null, XML_MNC_ATTR, UNSPECIFIED);

                if ((mcc == UNSPECIFIED) || (mnc == UNSPECIFIED)) {
                    continue;
                }

                String label = parser.getAttributeValue(null, XML_LABEL_ATTR);
                String icon = parser.getAttributeValue(null, XML_ICON_ATTR);

                Config config = new Config(mcc, mnc, label, icon);
                mArray.add(config);
            } while (true);
        } catch (Exception e) {
            CatLog.e(LOG_TAG, "Something wrong happened while interpreting the xml file" + e);
        } finally {
            parser.close();
        }
    }
}
