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

import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.SystemApi;
import android.os.Parcel;
import android.os.Parcelable;
import android.util.Log;

import java.util.Objects;
import java.util.regex.Pattern;

/**
 * This class is used to represent a range of phone numbers. Each range corresponds to a contiguous
 * block of phone numbers.
 *
 * Example:
 * {@code
 * {
 *     mCountryCode = "1"
 *     mPrefix = "650555"
 *     mLowerBound = "0055"
 *     mUpperBound = "0899"
 * }
 * }
 * would match 16505550089 and 6505550472, but not 63827593759 or 16505550900
 * @hide
 */
@SystemApi
public final class PhoneNumberRange implements Parcelable {
    public static final @android.annotation.NonNull Creator<PhoneNumberRange> CREATOR = new Creator<PhoneNumberRange>() {
        @Override
        public PhoneNumberRange createFromParcel(Parcel in) {
            return new PhoneNumberRange(in);
        }

        @Override
        public PhoneNumberRange[] newArray(int size) {
            return new PhoneNumberRange[size];
        }
    };

    private final String mCountryCode;
    private final String mPrefix;
    private final String mLowerBound;
    private final String mUpperBound;

    /**
     * @param countryCode The country code, omitting the leading "+"
     * @param prefix A prefix that all numbers matching the range must have.
     * @param lowerBound When concatenated with the prefix, represents the lower bound of phone
     *                   numbers that match this range.
     * @param upperBound When concatenated with the prefix, represents the upper bound of phone
     *                   numbers that match this range.
     */
    public PhoneNumberRange(@NonNull String countryCode, @NonNull String prefix,
            @NonNull String lowerBound, @NonNull String upperBound) {
        validateLowerAndUpperBounds(lowerBound, upperBound);
        if (!Pattern.matches("[0-9]*", countryCode)) {
            throw new IllegalArgumentException("Country code must be all numeric");
        }
        if (!Pattern.matches("[0-9]*", prefix)) {
            throw new IllegalArgumentException("Prefix must be all numeric");
        }
        mCountryCode = countryCode;
        mPrefix = prefix;
        mLowerBound = lowerBound;
        mUpperBound = upperBound;
    }

    private PhoneNumberRange(Parcel in) {
        mCountryCode = in.readString();
        mPrefix = in.readString();
        mLowerBound = in.readString();
        mUpperBound = in.readString();
    }

    @Override
    public void writeToParcel(Parcel dest, int flags) {
        dest.writeString(mCountryCode);
        dest.writeString(mPrefix);
        dest.writeString(mLowerBound);
        dest.writeString(mUpperBound);
    }

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

    @Override
    public boolean equals(@Nullable Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        PhoneNumberRange that = (PhoneNumberRange) o;
        return Objects.equals(mCountryCode, that.mCountryCode)
                && Objects.equals(mPrefix, that.mPrefix)
                && Objects.equals(mLowerBound, that.mLowerBound)
                && Objects.equals(mUpperBound, that.mUpperBound);
    }

    @Override
    public int hashCode() {
        return Objects.hash(mCountryCode, mPrefix, mLowerBound, mUpperBound);
    }

    @NonNull
    @Override
    public String toString() {
        return "PhoneNumberRange{"
                + "mCountryCode='" + mCountryCode + '\''
                + ", mPrefix='" + mPrefix + '\''
                + ", mLowerBound='" + mLowerBound + '\''
                + ", mUpperBound='" + mUpperBound + '\''
                + '}';
    }

    private void validateLowerAndUpperBounds(String lowerBound, String upperBound) {
        if (lowerBound.length() != upperBound.length()) {
            throw new IllegalArgumentException("Lower and upper bounds must have the same length");
        }
        if (!Pattern.matches("[0-9]*", lowerBound)) {
            throw new IllegalArgumentException("Lower bound must be all numeric");
        }
        if (!Pattern.matches("[0-9]*", upperBound)) {
            throw new IllegalArgumentException("Upper bound must be all numeric");
        }
        if (Integer.parseInt(lowerBound) > Integer.parseInt(upperBound)) {
            throw new IllegalArgumentException("Lower bound must be lower than upper bound");
        }
    }

    /**
     * Checks to see if the provided phone number matches this range.
     * @param number A phone number, with or without separators or a country code.
     * @return {@code true} if the number matches, {@code false} otherwise.
     */
    public boolean matches(@NonNull String number) {
        // Check the prefix, make sure it matches either with or without the country code.
        String normalizedNumber = number.replaceAll("[^0-9]", "");
        String prefixWithCountryCode = mCountryCode + mPrefix;
        String numberPostfix;
        if (normalizedNumber.startsWith(prefixWithCountryCode)) {
            numberPostfix = normalizedNumber.substring(prefixWithCountryCode.length());
        } else if (normalizedNumber.startsWith(mPrefix)) {
            numberPostfix = normalizedNumber.substring(mPrefix.length());
        } else {
            return false;
        }

        // Next check the postfix to make sure it lies within the bounds.
        try {
            int lower = Integer.parseInt(mLowerBound);
            int upper = Integer.parseInt(mUpperBound);
            int numberToCheck = Integer.parseInt(numberPostfix);
            return numberToCheck <= upper && numberToCheck >= lower;
        } catch (NumberFormatException e) {
            Log.e(PhoneNumberRange.class.getSimpleName(), "Invalid bounds or number.", e);
            return false;
        }
    }
}
