/*
 * Copyright (C) 2011 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.internal.telephony;

import android.annotation.UnsupportedAppUsage;
import android.app.AppGlobals;
import android.content.ContentResolver;
import android.content.Context;
import android.content.pm.ApplicationInfo;
import android.content.res.XmlResourceParser;
import android.database.ContentObserver;
import android.os.Binder;
import android.os.Handler;
import android.os.Process;
import android.os.RemoteException;
import android.os.UserHandle;
import android.provider.Settings;
import android.telephony.PhoneNumberUtils;
import android.telephony.Rlog;
import android.telephony.SmsManager;
import android.util.AtomicFile;
import android.util.Xml;

import com.android.internal.util.FastXmlSerializer;
import com.android.internal.util.XmlUtils;

import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
import org.xmlpull.v1.XmlSerializer;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.regex.Pattern;

/**
 * Implement the per-application based SMS control, which limits the number of
 * SMS/MMS messages an app can send in the checking period.
 *
 * This code was formerly part of {@link SMSDispatcher}, and has been moved
 * into a separate class to support instantiation of multiple SMSDispatchers on
 * dual-mode devices that require support for both 3GPP and 3GPP2 format messages.
 */
public class SmsUsageMonitor {
    private static final String TAG = "SmsUsageMonitor";
    private static final boolean DBG = false;
    private static final boolean VDBG = false;

    private static final String SHORT_CODE_PATH = "/data/misc/sms/codes";

    /** Default checking period for SMS sent without user permission. */
    private static final int DEFAULT_SMS_CHECK_PERIOD = 60000;      // 1 minute

    /** Default number of SMS sent in checking period without user permission. */
    private static final int DEFAULT_SMS_MAX_COUNT = 30;

    /** @hide */
    public static int mergeShortCodeCategories(int type1, int type2) {
        if (type1 > type2) return type1;
        return type2;
    }

    /** Premium SMS permission for a new package (ask user when first premium SMS sent). */
    public static final int PREMIUM_SMS_PERMISSION_UNKNOWN = 0;

    /** Default premium SMS permission (ask user for each premium SMS sent). */
    public static final int PREMIUM_SMS_PERMISSION_ASK_USER = 1;

    /** Premium SMS permission when the owner has denied the app from sending premium SMS. */
    public static final int PREMIUM_SMS_PERMISSION_NEVER_ALLOW = 2;

    /** Premium SMS permission when the owner has allowed the app to send premium SMS. */
    public static final int PREMIUM_SMS_PERMISSION_ALWAYS_ALLOW = 3;

    private final int mCheckPeriod;
    private final int mMaxAllowed;

    private final HashMap<String, ArrayList<Long>> mSmsStamp =
            new HashMap<String, ArrayList<Long>>();

    /** Context for retrieving regexes from XML resource. */
    private final Context mContext;

    /** Country code for the cached short code pattern matcher. */
    private String mCurrentCountry;

    /** Cached short code pattern matcher for {@link #mCurrentCountry}. */
    private ShortCodePatternMatcher mCurrentPatternMatcher;

    /** Notice when the enabled setting changes - can be changed through gservices */
    private final AtomicBoolean mCheckEnabled = new AtomicBoolean(true);

    /** Handler for responding to content observer updates. */
    private final SettingsObserverHandler mSettingsObserverHandler;

    /** File holding the patterns */
    private final File mPatternFile = new File(SHORT_CODE_PATH);

    /** Last modified time for pattern file */
    private long mPatternFileLastModified = 0;

    /** Directory for per-app SMS permission XML file. */
    private static final String SMS_POLICY_FILE_DIRECTORY = "/data/misc/sms";

    /** Per-app SMS permission XML filename. */
    private static final String SMS_POLICY_FILE_NAME = "premium_sms_policy.xml";

    /** XML tag for root element. */
    private static final String TAG_SHORTCODES = "shortcodes";

    /** XML tag for short code patterns for a specific country. */
    private static final String TAG_SHORTCODE = "shortcode";

    /** XML attribute for the country code. */
    private static final String ATTR_COUNTRY = "country";

    /** XML attribute for the short code regex pattern. */
    private static final String ATTR_PATTERN = "pattern";

    /** XML attribute for the premium short code regex pattern. */
    private static final String ATTR_PREMIUM = "premium";

    /** XML attribute for the free short code regex pattern. */
    private static final String ATTR_FREE = "free";

    /** XML attribute for the standard rate short code regex pattern. */
    private static final String ATTR_STANDARD = "standard";

    /** Stored copy of premium SMS package permissions. */
    private AtomicFile mPolicyFile;

    /** Loaded copy of premium SMS package permissions. */
    private final HashMap<String, Integer> mPremiumSmsPolicy = new HashMap<String, Integer>();

    /** XML tag for root element of premium SMS permissions. */
    private static final String TAG_SMS_POLICY_BODY = "premium-sms-policy";

    /** XML tag for a package. */
    private static final String TAG_PACKAGE = "package";

    /** XML attribute for the package name. */
    private static final String ATTR_PACKAGE_NAME = "name";

    /** XML attribute for the package's premium SMS permission (integer type). */
    private static final String ATTR_PACKAGE_SMS_POLICY = "sms-policy";

    /**
     * SMS short code regex pattern matcher for a specific country.
     */
    private static final class ShortCodePatternMatcher {
        private final Pattern mShortCodePattern;
        private final Pattern mPremiumShortCodePattern;
        private final Pattern mFreeShortCodePattern;
        private final Pattern mStandardShortCodePattern;

        ShortCodePatternMatcher(String shortCodeRegex, String premiumShortCodeRegex,
                String freeShortCodeRegex, String standardShortCodeRegex) {
            mShortCodePattern = (shortCodeRegex != null ? Pattern.compile(shortCodeRegex) : null);
            mPremiumShortCodePattern = (premiumShortCodeRegex != null ?
                    Pattern.compile(premiumShortCodeRegex) : null);
            mFreeShortCodePattern = (freeShortCodeRegex != null ?
                    Pattern.compile(freeShortCodeRegex) : null);
            mStandardShortCodePattern = (standardShortCodeRegex != null ?
                    Pattern.compile(standardShortCodeRegex) : null);
        }

        int getNumberCategory(String phoneNumber) {
            if (mFreeShortCodePattern != null && mFreeShortCodePattern.matcher(phoneNumber)
                    .matches()) {
                return SmsManager.SMS_CATEGORY_FREE_SHORT_CODE;
            }
            if (mStandardShortCodePattern != null && mStandardShortCodePattern.matcher(phoneNumber)
                    .matches()) {
                return SmsManager.SMS_CATEGORY_STANDARD_SHORT_CODE;
            }
            if (mPremiumShortCodePattern != null && mPremiumShortCodePattern.matcher(phoneNumber)
                    .matches()) {
                return SmsManager.SMS_CATEGORY_PREMIUM_SHORT_CODE;
            }
            if (mShortCodePattern != null && mShortCodePattern.matcher(phoneNumber).matches()) {
                return SmsManager.SMS_CATEGORY_POSSIBLE_PREMIUM_SHORT_CODE;
            }
            return SmsManager.SMS_CATEGORY_NOT_SHORT_CODE;
        }
    }

    /**
     * Observe the secure setting for enable flag
     */
    private static class SettingsObserver extends ContentObserver {
        private final Context mContext;
        private final AtomicBoolean mEnabled;

        SettingsObserver(Handler handler, Context context, AtomicBoolean enabled) {
            super(handler);
            mContext = context;
            mEnabled = enabled;
            onChange(false);
        }

        @Override
        public void onChange(boolean selfChange) {
            mEnabled.set(Settings.Global.getInt(mContext.getContentResolver(),
                    Settings.Global.SMS_SHORT_CODE_CONFIRMATION, 1) != 0);
        }
    }

    private static class SettingsObserverHandler extends Handler {
        SettingsObserverHandler(Context context, AtomicBoolean enabled) {
            ContentResolver resolver = context.getContentResolver();
            ContentObserver globalObserver = new SettingsObserver(this, context, enabled);
            resolver.registerContentObserver(Settings.Global.getUriFor(
                    Settings.Global.SMS_SHORT_CODE_CONFIRMATION), false, globalObserver);
        }
    }

    /**
     * Create SMS usage monitor.
     * @param context the context to use to load resources and get TelephonyManager service
     */
    @UnsupportedAppUsage
    public SmsUsageMonitor(Context context) {
        mContext = context;
        ContentResolver resolver = context.getContentResolver();

        mMaxAllowed = Settings.Global.getInt(resolver,
                Settings.Global.SMS_OUTGOING_CHECK_MAX_COUNT,
                DEFAULT_SMS_MAX_COUNT);

        mCheckPeriod = Settings.Global.getInt(resolver,
                Settings.Global.SMS_OUTGOING_CHECK_INTERVAL_MS,
                DEFAULT_SMS_CHECK_PERIOD);

        mSettingsObserverHandler = new SettingsObserverHandler(mContext, mCheckEnabled);

        loadPremiumSmsPolicyDb();
    }

    /**
     * Return a pattern matcher object for the specified country.
     * @param country the country to search for
     * @return a {@link ShortCodePatternMatcher} for the specified country, or null if not found
     */
    private ShortCodePatternMatcher getPatternMatcherFromFile(String country) {
        FileReader patternReader = null;
        XmlPullParser parser = null;
        try {
            patternReader = new FileReader(mPatternFile);
            parser = Xml.newPullParser();
            parser.setInput(patternReader);
            return getPatternMatcherFromXmlParser(parser, country);
        } catch (FileNotFoundException e) {
            Rlog.e(TAG, "Short Code Pattern File not found");
        } catch (XmlPullParserException e) {
            Rlog.e(TAG, "XML parser exception reading short code pattern file", e);
        } finally {
            mPatternFileLastModified = mPatternFile.lastModified();
            if (patternReader != null) {
                try {
                    patternReader.close();
                } catch (IOException e) {}
            }
        }
        return null;
    }

    private ShortCodePatternMatcher getPatternMatcherFromResource(String country) {
        int id = com.android.internal.R.xml.sms_short_codes;
        XmlResourceParser parser = null;
        try {
            parser = mContext.getResources().getXml(id);
            return getPatternMatcherFromXmlParser(parser, country);
        } finally {
            if (parser != null) parser.close();
        }
    }

    private ShortCodePatternMatcher getPatternMatcherFromXmlParser(XmlPullParser parser,
            String country) {
        try {
            XmlUtils.beginDocument(parser, TAG_SHORTCODES);

            while (true) {
                XmlUtils.nextElement(parser);
                String element = parser.getName();
                if (element == null) {
                    Rlog.e(TAG, "Parsing pattern data found null");
                    break;
                }

                if (element.equals(TAG_SHORTCODE)) {
                    String currentCountry = parser.getAttributeValue(null, ATTR_COUNTRY);
                    if (VDBG) Rlog.d(TAG, "Found country " + currentCountry);
                    if (country.equals(currentCountry)) {
                        String pattern = parser.getAttributeValue(null, ATTR_PATTERN);
                        String premium = parser.getAttributeValue(null, ATTR_PREMIUM);
                        String free = parser.getAttributeValue(null, ATTR_FREE);
                        String standard = parser.getAttributeValue(null, ATTR_STANDARD);
                        return new ShortCodePatternMatcher(pattern, premium, free, standard);
                    }
                } else {
                    Rlog.e(TAG, "Error: skipping unknown XML tag " + element);
                }
            }
        } catch (XmlPullParserException e) {
            Rlog.e(TAG, "XML parser exception reading short code patterns", e);
        } catch (IOException e) {
            Rlog.e(TAG, "I/O exception reading short code patterns", e);
        }
        if (DBG) Rlog.d(TAG, "Country (" + country + ") not found");
        return null;    // country not found
    }

    /** Clear the SMS application list for disposal. */
    void dispose() {
        mSmsStamp.clear();
    }

    /**
     * Check to see if an application is allowed to send new SMS messages, and confirm with
     * user if the send limit was reached or if a non-system app is potentially sending to a
     * premium SMS short code or number.
     *
     * @param appName the package name of the app requesting to send an SMS
     * @param smsWaiting the number of new messages desired to send
     * @return true if application is allowed to send the requested number
     *  of new sms messages
     */
    @UnsupportedAppUsage
    public boolean check(String appName, int smsWaiting) {
        synchronized (mSmsStamp) {
            removeExpiredTimestamps();

            ArrayList<Long> sentList = mSmsStamp.get(appName);
            if (sentList == null) {
                sentList = new ArrayList<Long>();
                mSmsStamp.put(appName, sentList);
            }

            return isUnderLimit(sentList, smsWaiting);
        }
    }

    /**
     * Check if the destination is a possible premium short code.
     * NOTE: the caller is expected to strip non-digits from the destination number with
     * {@link PhoneNumberUtils#extractNetworkPortion} before calling this method.
     * This happens in {@link SMSDispatcher#sendRawPdu} so that we use the same phone number
     * for testing and in the user confirmation dialog if the user needs to confirm the number.
     * This makes it difficult for malware to fool the user or the short code pattern matcher
     * by using non-ASCII characters to make the number appear to be different from the real
     * destination phone number.
     *
     * @param destAddress the destination address to test for possible short code
     * @return {@link SmsManager#SMS_CATEGORY_FREE_SHORT_CODE},
     * {@link SmsManager#SMS_CATEGORY_NOT_SHORT_CODE},
     *  {@link SmsManager#SMS_CATEGORY_POSSIBLE_PREMIUM_SHORT_CODE},
     *  {@link SmsManager#SMS_CATEGORY_STANDARD_SHORT_CODE}, or
     *  {@link SmsManager#SMS_CATEGORY_POSSIBLE_PREMIUM_SHORT_CODE}
     */
    public int checkDestination(String destAddress, String countryIso) {
        synchronized (mSettingsObserverHandler) {
            // always allow emergency numbers
            if (PhoneNumberUtils.isEmergencyNumber(destAddress, countryIso)) {
                if (DBG) Rlog.d(TAG, "isEmergencyNumber");
                return SmsManager.SMS_CATEGORY_NOT_SHORT_CODE;
            }
            // always allow if the feature is disabled
            if (!mCheckEnabled.get()) {
                if (DBG) Rlog.e(TAG, "check disabled");
                return SmsManager.SMS_CATEGORY_NOT_SHORT_CODE;
            }

            if (countryIso != null) {
                if (mCurrentCountry == null || !countryIso.equals(mCurrentCountry) ||
                        mPatternFile.lastModified() != mPatternFileLastModified) {
                    if (mPatternFile.exists()) {
                        if (DBG) Rlog.d(TAG, "Loading SMS Short Code patterns from file");
                        mCurrentPatternMatcher = getPatternMatcherFromFile(countryIso);
                    } else {
                        if (DBG) Rlog.d(TAG, "Loading SMS Short Code patterns from resource");
                        mCurrentPatternMatcher = getPatternMatcherFromResource(countryIso);
                    }
                    mCurrentCountry = countryIso;
                }
            }

            if (mCurrentPatternMatcher != null) {
                return mCurrentPatternMatcher.getNumberCategory(destAddress);
            } else {
                // Generic rule: numbers of 5 digits or less are considered potential short codes
                Rlog.e(TAG, "No patterns for \"" + countryIso + "\": using generic short code rule");
                if (destAddress.length() <= 5) {
                    return SmsManager.SMS_CATEGORY_POSSIBLE_PREMIUM_SHORT_CODE;
                } else {
                    return SmsManager.SMS_CATEGORY_NOT_SHORT_CODE;
                }
            }
        }
    }

    /**
     * Load the premium SMS policy from an XML file.
     * Based on code from NotificationManagerService.
     */
    private void loadPremiumSmsPolicyDb() {
        synchronized (mPremiumSmsPolicy) {
            if (mPolicyFile == null) {
                File dir = new File(SMS_POLICY_FILE_DIRECTORY);
                mPolicyFile = new AtomicFile(new File(dir, SMS_POLICY_FILE_NAME));

                mPremiumSmsPolicy.clear();

                FileInputStream infile = null;
                try {
                    infile = mPolicyFile.openRead();
                    final XmlPullParser parser = Xml.newPullParser();
                    parser.setInput(infile, StandardCharsets.UTF_8.name());

                    XmlUtils.beginDocument(parser, TAG_SMS_POLICY_BODY);

                    while (true) {
                        XmlUtils.nextElement(parser);

                        String element = parser.getName();
                        if (element == null) break;

                        if (element.equals(TAG_PACKAGE)) {
                            String packageName = parser.getAttributeValue(null, ATTR_PACKAGE_NAME);
                            String policy = parser.getAttributeValue(null, ATTR_PACKAGE_SMS_POLICY);
                            if (packageName == null) {
                                Rlog.e(TAG, "Error: missing package name attribute");
                            } else if (policy == null) {
                                Rlog.e(TAG, "Error: missing package policy attribute");
                            } else try {
                                mPremiumSmsPolicy.put(packageName, Integer.parseInt(policy));
                            } catch (NumberFormatException e) {
                                Rlog.e(TAG, "Error: non-numeric policy type " + policy);
                            }
                        } else {
                            Rlog.e(TAG, "Error: skipping unknown XML tag " + element);
                        }
                    }
                } catch (FileNotFoundException e) {
                    // No data yet
                } catch (IOException e) {
                    Rlog.e(TAG, "Unable to read premium SMS policy database", e);
                } catch (NumberFormatException e) {
                    Rlog.e(TAG, "Unable to parse premium SMS policy database", e);
                } catch (XmlPullParserException e) {
                    Rlog.e(TAG, "Unable to parse premium SMS policy database", e);
                } finally {
                    if (infile != null) {
                        try {
                            infile.close();
                        } catch (IOException ignored) {
                        }
                    }
                }
            }
        }
    }

    /**
     * Persist the premium SMS policy to an XML file.
     * Based on code from NotificationManagerService.
     */
    private void writePremiumSmsPolicyDb() {
        synchronized (mPremiumSmsPolicy) {
            FileOutputStream outfile = null;
            try {
                outfile = mPolicyFile.startWrite();

                XmlSerializer out = new FastXmlSerializer();
                out.setOutput(outfile, StandardCharsets.UTF_8.name());

                out.startDocument(null, true);

                out.startTag(null, TAG_SMS_POLICY_BODY);

                for (Map.Entry<String, Integer> policy : mPremiumSmsPolicy.entrySet()) {
                    out.startTag(null, TAG_PACKAGE);
                    out.attribute(null, ATTR_PACKAGE_NAME, policy.getKey());
                    out.attribute(null, ATTR_PACKAGE_SMS_POLICY, policy.getValue().toString());
                    out.endTag(null, TAG_PACKAGE);
                }

                out.endTag(null, TAG_SMS_POLICY_BODY);
                out.endDocument();

                mPolicyFile.finishWrite(outfile);
            } catch (IOException e) {
                Rlog.e(TAG, "Unable to write premium SMS policy database", e);
                if (outfile != null) {
                    mPolicyFile.failWrite(outfile);
                }
            }
        }
    }

    /**
     * Returns the premium SMS permission for the specified package. If the package has never
     * been seen before, the default {@link #PREMIUM_SMS_PERMISSION_ASK_USER}
     * will be returned.
     * @param packageName the name of the package to query permission
     * @return one of {@link #PREMIUM_SMS_PERMISSION_UNKNOWN},
     *  {@link #PREMIUM_SMS_PERMISSION_ASK_USER},
     *  {@link #PREMIUM_SMS_PERMISSION_NEVER_ALLOW}, or
     *  {@link #PREMIUM_SMS_PERMISSION_ALWAYS_ALLOW}
     * @throws SecurityException if the caller is not a system process
     */
    public int getPremiumSmsPermission(String packageName) {
        checkCallerIsSystemOrPhoneOrSameApp(packageName);
        synchronized (mPremiumSmsPolicy) {
            Integer policy = mPremiumSmsPolicy.get(packageName);
            if (policy == null) {
                return PREMIUM_SMS_PERMISSION_UNKNOWN;
            } else {
                return policy;
            }
        }
    }

    /**
     * Sets the premium SMS permission for the specified package and save the value asynchronously
     * to persistent storage.
     * @param packageName the name of the package to set permission
     * @param permission one of {@link #PREMIUM_SMS_PERMISSION_ASK_USER},
     *  {@link #PREMIUM_SMS_PERMISSION_NEVER_ALLOW}, or
     *  {@link #PREMIUM_SMS_PERMISSION_ALWAYS_ALLOW}
     * @throws SecurityException if the caller is not a system process
     */
    public void setPremiumSmsPermission(String packageName, int permission) {
        checkCallerIsSystemOrPhoneApp();
        if (permission < PREMIUM_SMS_PERMISSION_ASK_USER
                || permission > PREMIUM_SMS_PERMISSION_ALWAYS_ALLOW) {
            throw new IllegalArgumentException("invalid SMS permission type " + permission);
        }
        synchronized (mPremiumSmsPolicy) {
            mPremiumSmsPolicy.put(packageName, permission);
        }
        // write policy file in the background
        new Thread(new Runnable() {
            @Override
            public void run() {
                writePremiumSmsPolicyDb();
            }
        }).start();
    }

    private static void checkCallerIsSystemOrPhoneOrSameApp(String pkg) {
        int uid = Binder.getCallingUid();
        int appId = UserHandle.getAppId(uid);
        if (appId == Process.SYSTEM_UID || appId == Process.PHONE_UID || uid == 0) {
            return;
        }
        try {
            ApplicationInfo ai = AppGlobals.getPackageManager().getApplicationInfo(
                    pkg, 0, UserHandle.getCallingUserId());
            if (!UserHandle.isSameApp(ai.uid, uid)) {
                throw new SecurityException("Calling uid " + uid + " gave package"
                        + pkg + " which is owned by uid " + ai.uid);
            }
        } catch (RemoteException re) {
            throw new SecurityException("Unknown package " + pkg + "\n" + re);
        }
    }

    private static void checkCallerIsSystemOrPhoneApp() {
        int uid = Binder.getCallingUid();
        int appId = UserHandle.getAppId(uid);
        if (appId == Process.SYSTEM_UID || appId == Process.PHONE_UID || uid == 0) {
            return;
        }
        throw new SecurityException("Disallowed call for uid " + uid);
    }

    /**
     * Remove keys containing only old timestamps. This can happen if an SMS app is used
     * to send messages and then uninstalled.
     */
    private void removeExpiredTimestamps() {
        long beginCheckPeriod = System.currentTimeMillis() - mCheckPeriod;

        synchronized (mSmsStamp) {
            Iterator<Map.Entry<String, ArrayList<Long>>> iter = mSmsStamp.entrySet().iterator();
            while (iter.hasNext()) {
                Map.Entry<String, ArrayList<Long>> entry = iter.next();
                ArrayList<Long> oldList = entry.getValue();
                if (oldList.isEmpty() || oldList.get(oldList.size() - 1) < beginCheckPeriod) {
                    iter.remove();
                }
            }
        }
    }

    private boolean isUnderLimit(ArrayList<Long> sent, int smsWaiting) {
        Long ct = System.currentTimeMillis();
        long beginCheckPeriod = ct - mCheckPeriod;

        if (VDBG) log("SMS send size=" + sent.size() + " time=" + ct);

        while (!sent.isEmpty() && sent.get(0) < beginCheckPeriod) {
            sent.remove(0);
        }

        if ((sent.size() + smsWaiting) <= mMaxAllowed) {
            for (int i = 0; i < smsWaiting; i++ ) {
                sent.add(ct);
            }
            return true;
        }
        return false;
    }

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