/*
 * Copyright (C) 2011 Google Inc.
 *
 * 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.i18n.phonenumbers;

import com.android.i18n.phonenumbers.PhoneNumberUtil.Leniency;
import com.android.i18n.phonenumbers.Phonenumber.PhoneNumber;

import junit.framework.TestCase;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
import java.util.NoSuchElementException;

/**
 * Tests for {@link PhoneNumberMatcher}. This only tests basic functionality based on test metadata.
 *
 * @author Tom Hofmann
 * @see PhoneNumberUtilTest {@link PhoneNumberUtilTest} for the origin of the test data
 */
public class PhoneNumberMatcherTest extends TestCase {
  private PhoneNumberUtil phoneUtil;

  @Override
  protected void setUp() throws Exception {
    phoneUtil = PhoneNumberUtilTest.initializePhoneUtilForTesting();
  }

  /** See {@link PhoneNumberUtilTest#testParseNationalNumber()}. */
  public void testFindNationalNumber() throws Exception {
    // same cases as in testParseNationalNumber
    doTestFindInContext("033316005", "NZ");
    doTestFindInContext("33316005", "NZ");
    // National prefix attached and some formatting present.
    doTestFindInContext("03-331 6005", "NZ");
    doTestFindInContext("03 331 6005", "NZ");
    // Testing international prefixes.
    // Should strip country code.
    doTestFindInContext("0064 3 331 6005", "NZ");
    // Try again, but this time we have an international number with Region Code US. It should
    // recognize the country code and parse accordingly.
    doTestFindInContext("01164 3 331 6005", "US");
    doTestFindInContext("+64 3 331 6005", "US");

    doTestFindInContext("64(0)64123456", "NZ");
    // Check that using a "/" is fine in a phone number.
    doTestFindInContext("123/45678", "DE");
    doTestFindInContext("123-456-7890", "US");
  }

  /** See {@link PhoneNumberUtilTest#testParseWithInternationalPrefixes()}. */
  public void testFindWithInternationalPrefixes() throws Exception {
    doTestFindInContext("+1 (650) 333-6000", "NZ");
    doTestFindInContext("1-650-333-6000", "US");
    // Calling the US number from Singapore by using different service providers
    // 1st test: calling using SingTel IDD service (IDD is 001)
    doTestFindInContext("0011-650-333-6000", "SG");
    // 2nd test: calling using StarHub IDD service (IDD is 008)
    doTestFindInContext("0081-650-333-6000", "SG");
    // 3rd test: calling using SingTel V019 service (IDD is 019)
    doTestFindInContext("0191-650-333-6000", "SG");
    // Calling the US number from Poland
    doTestFindInContext("0~01-650-333-6000", "PL");
    // Using "++" at the start.
    doTestFindInContext("++1 (650) 333-6000", "PL");
    // Using a full-width plus sign.
    doTestFindInContext("\uFF0B1 (650) 333-6000", "SG");
    // The whole number, including punctuation, is here represented in full-width form.
    doTestFindInContext("\uFF0B\uFF11\u3000\uFF08\uFF16\uFF15\uFF10\uFF09" +
        "\u3000\uFF13\uFF13\uFF13\uFF0D\uFF16\uFF10\uFF10\uFF10",
        "SG");
  }

  /** See {@link PhoneNumberUtilTest#testParseWithLeadingZero()}. */
  public void testFindWithLeadingZero() throws Exception {
    doTestFindInContext("+39 02-36618 300", "NZ");
    doTestFindInContext("02-36618 300", "IT");
    doTestFindInContext("312 345 678", "IT");
  }

  /** See {@link PhoneNumberUtilTest#testParseNationalNumberArgentina()}. */
  public void testFindNationalNumberArgentina() throws Exception {
    // Test parsing mobile numbers of Argentina.
    doTestFindInContext("+54 9 343 555 1212", "AR");
    doTestFindInContext("0343 15 555 1212", "AR");

    doTestFindInContext("+54 9 3715 65 4320", "AR");
    doTestFindInContext("03715 15 65 4320", "AR");

    // Test parsing fixed-line numbers of Argentina.
    doTestFindInContext("+54 11 3797 0000", "AR");
    doTestFindInContext("011 3797 0000", "AR");

    doTestFindInContext("+54 3715 65 4321", "AR");
    doTestFindInContext("03715 65 4321", "AR");

    doTestFindInContext("+54 23 1234 0000", "AR");
    doTestFindInContext("023 1234 0000", "AR");
  }

  /** See {@link PhoneNumberUtilTest#testParseWithXInNumber()}. */
  public void testFindWithXInNumber() throws Exception {
    doTestFindInContext("(0xx) 123456789", "AR");
    // A case where x denotes both carrier codes and extension symbol.
    doTestFindInContext("(0xx) 123456789 x 1234", "AR");

    // This test is intentionally constructed such that the number of digit after xx is larger than
    // 7, so that the number won't be mistakenly treated as an extension, as we allow extensions up
    // to 7 digits. This assumption is okay for now as all the countries where a carrier selection
    // code is written in the form of xx have a national significant number of length larger than 7.
    doTestFindInContext("011xx5481429712", "US");
  }

  /** See {@link PhoneNumberUtilTest#testParseNumbersMexico()}. */
  public void testFindNumbersMexico() throws Exception {
    // Test parsing fixed-line numbers of Mexico.
    doTestFindInContext("+52 (449)978-0001", "MX");
    doTestFindInContext("01 (449)978-0001", "MX");
    doTestFindInContext("(449)978-0001", "MX");

    // Test parsing mobile numbers of Mexico.
    doTestFindInContext("+52 1 33 1234-5678", "MX");
    doTestFindInContext("044 (33) 1234-5678", "MX");
    doTestFindInContext("045 33 1234-5678", "MX");
  }

  /** See {@link PhoneNumberUtilTest#testParseNumbersWithPlusWithNoRegion()}. */
  public void testFindNumbersWithPlusWithNoRegion() throws Exception {
    // "ZZ" is allowed only if the number starts with a '+' - then the country code can be
    // calculated.
    doTestFindInContext("+64 3 331 6005", "ZZ");
    // Null is also allowed for the region code in these cases.
    doTestFindInContext("+64 3 331 6005", null);
  }

  /** See {@link PhoneNumberUtilTest#testParseExtensions()}. */
  public void testFindExtensions() throws Exception {
    doTestFindInContext("03 331 6005 ext 3456", "NZ");
    doTestFindInContext("03-3316005x3456", "NZ");
    doTestFindInContext("03-3316005 int.3456", "NZ");
    doTestFindInContext("03 3316005 #3456", "NZ");
    doTestFindInContext("0~0 1800 7493 524", "PL");
    doTestFindInContext("(1800) 7493.524", "US");
    // Check that the last instance of an extension token is matched.
    doTestFindInContext("0~0 1800 7493 524 ~1234", "PL");
    // Verifying bug-fix where the last digit of a number was previously omitted if it was a 0 when
    // extracting the extension. Also verifying a few different cases of extensions.
    doTestFindInContext("+44 2034567890x456", "NZ");
    doTestFindInContext("+44 2034567890x456", "GB");
    doTestFindInContext("+44 2034567890 x456", "GB");
    doTestFindInContext("+44 2034567890 X456", "GB");
    doTestFindInContext("+44 2034567890 X 456", "GB");
    doTestFindInContext("+44 2034567890 X  456", "GB");
    doTestFindInContext("+44 2034567890  X 456", "GB");

    doTestFindInContext("(800) 901-3355 x 7246433", "US");
    doTestFindInContext("(800) 901-3355 , ext 7246433", "US");
    doTestFindInContext("(800) 901-3355 ,extension 7246433", "US");
    // The next test differs from PhoneNumberUtil -> when matching we don't consider a lone comma to
    // indicate an extension, although we accept it when parsing.
    doTestFindInContext("(800) 901-3355 ,x 7246433", "US");
    doTestFindInContext("(800) 901-3355 ext: 7246433", "US");
  }

  public void testFindInterspersedWithSpace() throws Exception {
    doTestFindInContext("0 3   3 3 1   6 0 0 5", "NZ");
  }

  /**
   * Test matching behavior when starting in the middle of a phone number.
   */
  public void testIntermediateParsePositions() throws Exception {
    String text = "Call 033316005  or 032316005!";
    //             |    |    |    |    |    |
    //             0    5   10   15   20   25

    // Iterate over all possible indices.
    for (int i = 0; i <= 5; i++) {
      assertEqualRange(text, i, 5, 14);
    }
    // 7 and 8 digits in a row are still parsed as number.
    assertEqualRange(text, 6, 6, 14);
    assertEqualRange(text, 7, 7, 14);
    // Anything smaller is skipped to the second instance.
    for (int i = 8; i <= 19; i++) {
      assertEqualRange(text, i, 19, 28);
    }
  }

  public void testMatchWithSurroundingZipcodes() throws Exception {
    String number = "415-666-7777";
    String zipPreceding = "My address is CA 34215 - " + number + " is my number.";
    PhoneNumber expectedResult = phoneUtil.parse(number, "US");

    Iterator<PhoneNumberMatch> iterator =
        phoneUtil.findNumbers(zipPreceding, "US").iterator();
    PhoneNumberMatch match = iterator.hasNext() ? iterator.next() : null;
    assertNotNull("Did not find a number in '" + zipPreceding + "'; expected " + number, match);
    assertEquals(expectedResult, match.number());
    assertEquals(number, match.rawString());

    // Now repeat, but this time the phone number has spaces in it. It should still be found.
    number = "(415) 666 7777";

    String zipFollowing = "My number is " + number + ". 34215 is my zip-code.";
    iterator = phoneUtil.findNumbers(zipFollowing, "US").iterator();

    PhoneNumberMatch matchWithSpaces = iterator.hasNext() ? iterator.next() : null;
    assertNotNull("Did not find a number in '" + zipFollowing + "'; expected " + number,
                  matchWithSpaces);
    assertEquals(expectedResult, matchWithSpaces.number());
    assertEquals(number, matchWithSpaces.rawString());
  }

  public void testIsLatinLetter() throws Exception {
    assertTrue(PhoneNumberMatcher.isLatinLetter('c'));
    assertTrue(PhoneNumberMatcher.isLatinLetter('C'));
    assertTrue(PhoneNumberMatcher.isLatinLetter('\u00C9'));
    assertTrue(PhoneNumberMatcher.isLatinLetter('\u0301'));  // Combining acute accent
    // Punctuation, digits and white-space are not considered "latin letters".
    assertFalse(PhoneNumberMatcher.isLatinLetter(':'));
    assertFalse(PhoneNumberMatcher.isLatinLetter('5'));
    assertFalse(PhoneNumberMatcher.isLatinLetter('-'));
    assertFalse(PhoneNumberMatcher.isLatinLetter('.'));
    assertFalse(PhoneNumberMatcher.isLatinLetter(' '));
    assertFalse(PhoneNumberMatcher.isLatinLetter('\u6211'));  // Chinese character
  }

  public void testMatchesWithSurroundingLatinChars() throws Exception {
    ArrayList<NumberContext> possibleOnlyContexts = new ArrayList<NumberContext>();
    possibleOnlyContexts.add(new NumberContext("abc", "def"));
    possibleOnlyContexts.add(new NumberContext("abc", ""));
    possibleOnlyContexts.add(new NumberContext("", "def"));
    // Latin capital letter e with an acute accent.
    possibleOnlyContexts.add(new NumberContext("\u00C9", ""));
    // e with an acute accent decomposed (with combining mark).
    possibleOnlyContexts.add(new NumberContext("e\u0301", ""));

    // Numbers should not be considered valid, if they are surrounded by Latin characters, but
    // should be considered possible.
    findMatchesInContexts(possibleOnlyContexts, false, true);
  }

  public void testMoneyNotSeenAsPhoneNumber() throws Exception {
    ArrayList<NumberContext> possibleOnlyContexts = new ArrayList<NumberContext>();
    possibleOnlyContexts.add(new NumberContext("$", ""));
    possibleOnlyContexts.add(new NumberContext("", "$"));
    possibleOnlyContexts.add(new NumberContext("\u00A3", ""));  // Pound sign
    possibleOnlyContexts.add(new NumberContext("\u00A5", ""));  // Yen sign
    findMatchesInContexts(possibleOnlyContexts, false, true);
  }

  public void testPhoneNumberWithLeadingOrTrailingMoneyMatches() throws Exception {
    // Because of the space after the 20 (or before the 100) these dollar amounts should not stop
    // the actual number from being found.
    ArrayList<NumberContext> contexts = new ArrayList<NumberContext>();
    contexts.add(new NumberContext("$20 ", ""));
    contexts.add(new NumberContext("", " 100$"));
    findMatchesInContexts(contexts, true, true);
  }

  public void testMatchesWithSurroundingLatinCharsAndLeadingPunctuation() throws Exception {
    // Contexts with trailing characters. Leading characters are okay here since the numbers we will
    // insert start with punctuation, but trailing characters are still not allowed.
    ArrayList<NumberContext> possibleOnlyContexts = new ArrayList<NumberContext>();
    possibleOnlyContexts.add(new NumberContext("abc", "def"));
    possibleOnlyContexts.add(new NumberContext("", "def"));
    possibleOnlyContexts.add(new NumberContext("", "\u00C9"));

    // Numbers should not be considered valid, if they have trailing Latin characters, but should be
    // considered possible.
    String numberWithPlus = "+14156667777";
    String numberWithBrackets = "(415)6667777";
    findMatchesInContexts(possibleOnlyContexts, false, true, "US", numberWithPlus);
    findMatchesInContexts(possibleOnlyContexts, false, true, "US", numberWithBrackets);

    ArrayList<NumberContext> validContexts = new ArrayList<NumberContext>();
    validContexts.add(new NumberContext("abc", ""));
    validContexts.add(new NumberContext("\u00C9", ""));
    validContexts.add(new NumberContext("\u00C9", "."));  // Trailing punctuation.
    validContexts.add(new NumberContext("\u00C9", " def"));  // Trailing white-space.

    // Numbers should be considered valid, since they start with punctuation.
    findMatchesInContexts(validContexts, true, true, "US", numberWithPlus);
    findMatchesInContexts(validContexts, true, true, "US", numberWithBrackets);
  }

  public void testMatchesWithSurroundingChineseChars() throws Exception {
    ArrayList<NumberContext> validContexts = new ArrayList<NumberContext>();
    validContexts.add(new NumberContext("\u6211\u7684\u7535\u8BDD\u53F7\u7801\u662F", ""));
    validContexts.add(new NumberContext("", "\u662F\u6211\u7684\u7535\u8BDD\u53F7\u7801"));
    validContexts.add(new NumberContext("\u8BF7\u62E8\u6253", "\u6211\u5728\u660E\u5929"));

    // Numbers should be considered valid, since they are surrounded by Chinese.
    findMatchesInContexts(validContexts, true, true);
  }

  public void testMatchesWithSurroundingPunctuation() throws Exception {
    ArrayList<NumberContext> validContexts = new ArrayList<NumberContext>();
    validContexts.add(new NumberContext("My number-", ""));  // At end of text.
    validContexts.add(new NumberContext("", ".Nice day."));  // At start of text.
    validContexts.add(new NumberContext("Tel:", "."));  // Punctuation surrounds number.
    validContexts.add(new NumberContext("Tel: ", " on Saturdays."));  // White-space is also fine.

    // Numbers should be considered valid, since they are surrounded by punctuation.
    findMatchesInContexts(validContexts, true, true);
  }

  public void testMatchesMultiplePhoneNumbersSeparatedByPhoneNumberPunctuation() throws Exception {
    String text = "Call 650-253-4561 -- 455-234-3451";
    String region = "US";

    PhoneNumber number1 = new PhoneNumber();
    number1.setCountryCode(phoneUtil.getCountryCodeForRegion(region));
    number1.setNationalNumber(6502534561L);
    PhoneNumberMatch match1 = new PhoneNumberMatch(5, "650-253-4561", number1);

    PhoneNumber number2 = new PhoneNumber();
    number2.setCountryCode(phoneUtil.getCountryCodeForRegion(region));
    number2.setNationalNumber(4552343451L);
    PhoneNumberMatch match2 = new PhoneNumberMatch(21, "455-234-3451", number2);

    Iterator<PhoneNumberMatch> matches = phoneUtil.findNumbers(text, region).iterator();
    assertEquals(match1, matches.next());
    assertEquals(match2, matches.next());
  }

  public void testDoesNotMatchMultiplePhoneNumbersSeparatedWithNoWhiteSpace() throws Exception {
    // No white-space found between numbers - neither is found.
    String text = "Call 650-253-4561--455-234-3451";
    String region = "US";

    assertTrue(hasNoMatches(phoneUtil.findNumbers(text, region)));
  }

  /**
   * Strings with number-like things that shouldn't be found under any level.
   */
  private static final NumberTest[] IMPOSSIBLE_CASES = {
    new NumberTest("12345", "US"),
    new NumberTest("23456789", "US"),
    new NumberTest("234567890112", "US"),
    new NumberTest("650+253+1234", "US"),
    new NumberTest("3/10/1984", "CA"),
    new NumberTest("03/27/2011", "US"),
    new NumberTest("31/8/2011", "US"),
    new NumberTest("1/12/2011", "US"),
    new NumberTest("10/12/82", "DE"),
  };

  /**
   * Strings with number-like things that should only be found under "possible".
   */
  private static final NumberTest[] POSSIBLE_ONLY_CASES = {
    new NumberTest("abc8002345678", "US"),
    // US numbers cannot start with 7 in the test metadata to be valid.
    new NumberTest("7121115678", "US"),
    // 'X' should not be found in numbers at leniencies stricter than POSSIBLE, unless it represents
    // a carrier code or extension.
    new NumberTest("1650 x 253 - 1234", "US"),
    new NumberTest("650 x 253 - 1234", "US"),
    new NumberTest("650x2531234", "US"),
  };

  /**
   * Strings with number-like things that should only be found up to and including the "valid"
   * leniency level.
   */
  private static final NumberTest[] VALID_CASES = {
    new NumberTest("65 02 53 00 00.", "US"),
    new NumberTest("6502 538365", "US"),
    new NumberTest("650//253-1234", "US"),  // 2 slashes are illegal at higher levels
    new NumberTest("650/253/1234", "US"),
    new NumberTest("9002309. 158", "US"),
    new NumberTest("21 7/8 - 14 12/34 - 5", "US"),
    new NumberTest("12.1 - 23.71 - 23.45", "US"),
    new NumberTest("1979-2011 100%", "US"),
    new NumberTest("800 234 1 111x1111", "US"),
    new NumberTest("+494949-4-94", "DE"),  // National number in wrong format
  };

  /**
   * Strings with number-like things that should only be found up to and including the
   * "strict_grouping" leniency level.
   */
  private static final NumberTest[] STRICT_GROUPING_CASES = {
    new NumberTest("(415) 6667777", "US"),
    new NumberTest("415-6667777", "US"),
    // Should be found by strict grouping but not exact grouping, as the last two groups are
    // formatted together as a block.
    new NumberTest("800-2491234", "DE"),
  };

  /**
   * Strings with number-like things that should found at all levels.
   */
  private static final NumberTest[] EXACT_GROUPING_CASES = {
    new NumberTest("\uFF14\uFF11\uFF15\uFF16\uFF16\uFF16\uFF17\uFF17\uFF17\uFF17", "US"),
    new NumberTest("\uFF14\uFF11\uFF15-\uFF16\uFF16\uFF16-\uFF17\uFF17\uFF17\uFF17", "US"),
    new NumberTest("4156667777", "US"),
    new NumberTest("4156667777 x 123", "US"),
    new NumberTest("415-666-7777", "US"),
    new NumberTest("415/666-7777", "US"),
    new NumberTest("415-666-7777 ext. 503", "US"),
    new NumberTest("1 415 666 7777 x 123", "US"),
    new NumberTest("+1 415-666-7777", "US"),
    new NumberTest("+494949 49", "DE"),
    new NumberTest("+49-49-34", "DE"),
    new NumberTest("+49-4931-49", "DE"),
    new NumberTest("04931-49", "DE"),  // With National Prefix
    new NumberTest("+49-494949", "DE"),  // One group with country code
    new NumberTest("+49-494949 ext. 49", "DE"),
    new NumberTest("+49494949 ext. 49", "DE"),
    new NumberTest("0494949", "DE"),
    new NumberTest("0494949 ext. 49", "DE"),
  };

  public void testMatchesWithStrictGroupingLeniency() throws Exception {
    int noMatchFoundCount = 0;
    int wrongMatchFoundCount = 0;
    List<NumberTest> testCases = new ArrayList<NumberTest>();
    testCases.addAll(Arrays.asList(STRICT_GROUPING_CASES));
    testCases.addAll(Arrays.asList(EXACT_GROUPING_CASES));
    doTestNumberMatchesForLeniency(testCases, Leniency.STRICT_GROUPING);
  }

  public void testNonMatchesWithStrictGroupLeniency() throws Exception {
    int matchFoundCount = 0;
    List<NumberTest> testCases = new ArrayList<NumberTest>();
    testCases.addAll(Arrays.asList(POSSIBLE_ONLY_CASES));
    testCases.addAll(Arrays.asList(VALID_CASES));
    doTestNumberNonMatchesForLeniency(testCases, Leniency.STRICT_GROUPING);
  }

  public void testMatchesWithExactGroupingLeniency() throws Exception {
    List<NumberTest> testCases = new ArrayList<NumberTest>();
    testCases.addAll(Arrays.asList(EXACT_GROUPING_CASES));
    doTestNumberMatchesForLeniency(testCases, Leniency.EXACT_GROUPING);
  }

  public void testNonMatchesExactGroupLeniency() throws Exception {
    List<NumberTest> testCases = new ArrayList<NumberTest>();
    testCases.addAll(Arrays.asList(POSSIBLE_ONLY_CASES));
    testCases.addAll(Arrays.asList(VALID_CASES));
    testCases.addAll(Arrays.asList(STRICT_GROUPING_CASES));
    doTestNumberNonMatchesForLeniency(testCases, Leniency.EXACT_GROUPING);
  }

  private void doTestNumberMatchesForLeniency(List<NumberTest> testCases,
                                              PhoneNumberUtil.Leniency leniency) {
    int noMatchFoundCount = 0;
    int wrongMatchFoundCount = 0;
    for (NumberTest test : testCases) {
      Iterator<PhoneNumberMatch> iterator =
          findNumbersForLeniency(test.rawString, test.region, leniency);
      PhoneNumberMatch match = iterator.hasNext() ? iterator.next() : null;
      if (match == null) {
        noMatchFoundCount++;
        System.err.println("No match found in " + test.toString() + " for leniency: " + leniency);
      } else {
        if (!test.rawString.equals(match.rawString())) {
          wrongMatchFoundCount++;
          System.err.println("Found wrong match in test " + test.toString() +
                             ". Found " + match.rawString());
        }
      }
    }
    assertEquals(0, noMatchFoundCount);
    assertEquals(0, wrongMatchFoundCount);
  }

  private void doTestNumberNonMatchesForLeniency(List<NumberTest> testCases,
                                                 PhoneNumberUtil.Leniency leniency) {
    int matchFoundCount = 0;
    for (NumberTest test : testCases) {
      Iterator<PhoneNumberMatch> iterator =
          findNumbersForLeniency(test.rawString, test.region, leniency);
      PhoneNumberMatch match = iterator.hasNext() ? iterator.next() : null;
      if (match != null) {
        matchFoundCount++;
        System.err.println("Match found in " + test.toString() + " for leniency: " + leniency);
      }
    }
    assertEquals(0, matchFoundCount);
  }

  /**
   * Helper method which tests the contexts provided and ensures that:
   * -- if isValid is true, they all find a test number inserted in the middle when leniency of
   *  matching is set to VALID; else no test number should be extracted at that leniency level
   * -- if isPossible is true, they all find a test number inserted in the middle when leniency of
   *  matching is set to POSSIBLE; else no test number should be extracted at that leniency level
   */
  private void findMatchesInContexts(List<NumberContext> contexts, boolean isValid,
                                     boolean isPossible, String region, String number) {
    if (isValid) {
      doTestInContext(number, region, contexts, Leniency.VALID);
    } else {
      for (NumberContext context : contexts) {
        String text = context.leadingText + number + context.trailingText;
        assertTrue("Should not have found a number in " + text,
                   hasNoMatches(phoneUtil.findNumbers(text, region)));
      }
    }
    if (isPossible) {
      doTestInContext(number, region, contexts, Leniency.POSSIBLE);
    } else {
      for (NumberContext context : contexts) {
        String text = context.leadingText + number + context.trailingText;
        assertTrue("Should not have found a number in " + text,
                   hasNoMatches(phoneUtil.findNumbers(text, region, Leniency.POSSIBLE,
                                                      Long.MAX_VALUE)));
      }
    }
  }

  /**
   * Variant of findMatchesInContexts that uses a default number and region.
   */
  private void findMatchesInContexts(List<NumberContext> contexts, boolean isValid,
                                     boolean isPossible) {
    String region = "US";
    String number = "415-666-7777";

    findMatchesInContexts(contexts, isValid, isPossible, region, number);
  }

  public void testNonMatchingBracketsAreInvalid() throws Exception {
    // The digits up to the ", " form a valid US number, but it shouldn't be matched as one since
    // there was a non-matching bracket present.
    assertTrue(hasNoMatches(phoneUtil.findNumbers(
        "80.585 [79.964, 81.191]", "US")));

    // The trailing "]" is thrown away before parsing, so the resultant number, while a valid US
    // number, does not have matching brackets.
    assertTrue(hasNoMatches(phoneUtil.findNumbers(
        "80.585 [79.964]", "US")));

    assertTrue(hasNoMatches(phoneUtil.findNumbers(
        "80.585 ((79.964)", "US")));

    // This case has too many sets of brackets to be valid.
    assertTrue(hasNoMatches(phoneUtil.findNumbers(
        "(80).(585) (79).(9)64", "US")));
  }

  public void testNoMatchIfRegionIsNull() throws Exception {
    // Fail on non-international prefix if region code is null.
    assertTrue(hasNoMatches(phoneUtil.findNumbers(
        "Random text body - number is 0331 6005, see you there", null)));
  }

  public void testNoMatchInEmptyString() throws Exception {
    assertTrue(hasNoMatches(phoneUtil.findNumbers("", "US")));
    assertTrue(hasNoMatches(phoneUtil.findNumbers("  ", "US")));
  }

  public void testNoMatchIfNoNumber() throws Exception {
    assertTrue(hasNoMatches(phoneUtil.findNumbers(
        "Random text body - number is foobar, see you there", "US")));
  }

  public void testSequences() throws Exception {
    // Test multiple occurrences.
    String text = "Call 033316005  or 032316005!";
    String region = "NZ";

    PhoneNumber number1 = new PhoneNumber();
    number1.setCountryCode(phoneUtil.getCountryCodeForRegion(region));
    number1.setNationalNumber(33316005);
    PhoneNumberMatch match1 = new PhoneNumberMatch(5, "033316005", number1);

    PhoneNumber number2 = new PhoneNumber();
    number2.setCountryCode(phoneUtil.getCountryCodeForRegion(region));
    number2.setNationalNumber(32316005);
    PhoneNumberMatch match2 = new PhoneNumberMatch(19, "032316005", number2);

    Iterator<PhoneNumberMatch> matches =
        phoneUtil.findNumbers(text, region, Leniency.POSSIBLE, Long.MAX_VALUE).iterator();

    assertEquals(match1, matches.next());
    assertEquals(match2, matches.next());
  }

  public void testNullInput() throws Exception {
    assertTrue(hasNoMatches(phoneUtil.findNumbers(null, "US")));
    assertTrue(hasNoMatches(phoneUtil.findNumbers(null, null)));
  }

  public void testMaxMatches() throws Exception {
    // Set up text with 100 valid phone numbers.
    StringBuilder numbers = new StringBuilder();
    for (int i = 0; i < 100; i++) {
      numbers.append("My info: 415-666-7777,");
    }

    // Matches all 100. Max only applies to failed cases.
    List<PhoneNumber> expected = new ArrayList<PhoneNumber>(100);
    PhoneNumber number = phoneUtil.parse("+14156667777", null);
    for (int i = 0; i < 100; i++) {
      expected.add(number);
    }

    Iterable<PhoneNumberMatch> iterable =
        phoneUtil.findNumbers(numbers.toString(), "US", Leniency.VALID, 10);
    List<PhoneNumber> actual = new ArrayList<PhoneNumber>(100);
    for (PhoneNumberMatch match : iterable) {
      actual.add(match.number());
    }
    assertEquals(expected, actual);
  }

  public void testMaxMatchesInvalid() throws Exception {
    // Set up text with 10 invalid phone numbers followed by 100 valid.
    StringBuilder numbers = new StringBuilder();
    for (int i = 0; i < 10; i++) {
      numbers.append("My address 949-8945-0");
    }
    for (int i = 0; i < 100; i++) {
      numbers.append("My info: 415-666-7777,");
    }

    Iterable<PhoneNumberMatch> iterable =
        phoneUtil.findNumbers(numbers.toString(), "US", Leniency.VALID, 10);
    assertFalse(iterable.iterator().hasNext());
  }

  public void testMaxMatchesMixed() throws Exception {
    // Set up text with 100 valid numbers inside an invalid number.
    StringBuilder numbers = new StringBuilder();
    for (int i = 0; i < 100; i++) {
      numbers.append("My info: 415-666-7777 123 fake street");
    }

    // Only matches the first 10 despite there being 100 numbers due to max matches.
    List<PhoneNumber> expected = new ArrayList<PhoneNumber>(100);
    PhoneNumber number = phoneUtil.parse("+14156667777", null);
    for (int i = 0; i < 10; i++) {
      expected.add(number);
    }

    Iterable<PhoneNumberMatch> iterable =
        phoneUtil.findNumbers(numbers.toString(), "US", Leniency.VALID, 10);
    List<PhoneNumber> actual = new ArrayList<PhoneNumber>(100);
    for (PhoneNumberMatch match : iterable) {
      actual.add(match.number());
    }
    assertEquals(expected, actual);
  }

  public void testEmptyIteration() throws Exception {
    Iterable<PhoneNumberMatch> iterable = phoneUtil.findNumbers("", "ZZ");
    Iterator<PhoneNumberMatch> iterator = iterable.iterator();

    assertFalse(iterator.hasNext());
    assertFalse(iterator.hasNext());
    try {
      iterator.next();
      fail("Violation of the Iterator contract.");
    } catch (NoSuchElementException e) { /* Success */ }
    assertFalse(iterator.hasNext());
  }

  public void testSingleIteration() throws Exception {
    Iterable<PhoneNumberMatch> iterable = phoneUtil.findNumbers("+14156667777", "ZZ");

    // With hasNext() -> next().
    Iterator<PhoneNumberMatch> iterator = iterable.iterator();
    // Double hasNext() to ensure it does not advance.
    assertTrue(iterator.hasNext());
    assertTrue(iterator.hasNext());
    assertNotNull(iterator.next());
    assertFalse(iterator.hasNext());
    try {
      iterator.next();
      fail("Violation of the Iterator contract.");
    } catch (NoSuchElementException e) { /* Success */ }
    assertFalse(iterator.hasNext());

    // With next() only.
    iterator = iterable.iterator();
    assertNotNull(iterator.next());
    try {
      iterator.next();
      fail("Violation of the Iterator contract.");
    } catch (NoSuchElementException e) { /* Success */ }
  }

  public void testDoubleIteration() throws Exception {
    Iterable<PhoneNumberMatch> iterable =
        phoneUtil.findNumbers("+14156667777 foobar +14156667777 ", "ZZ");

    // With hasNext() -> next().
    Iterator<PhoneNumberMatch> iterator = iterable.iterator();
    // Double hasNext() to ensure it does not advance.
    assertTrue(iterator.hasNext());
    assertTrue(iterator.hasNext());
    assertNotNull(iterator.next());
    assertTrue(iterator.hasNext());
    assertTrue(iterator.hasNext());
    assertNotNull(iterator.next());
    assertFalse(iterator.hasNext());
    try {
      iterator.next();
      fail("Violation of the Iterator contract.");
    } catch (NoSuchElementException e) { /* Success */ }
    assertFalse(iterator.hasNext());

    // With next() only.
    iterator = iterable.iterator();
    assertNotNull(iterator.next());
    assertNotNull(iterator.next());
    try {
      iterator.next();
      fail("Violation of the Iterator contract.");
    } catch (NoSuchElementException e) { /* Success */ }
  }

  /**
   * Ensures that {@link Iterator#remove()} is not supported and that calling it does not
   * change iteration behavior.
   */
  public void testRemovalNotSupported() throws Exception {
    Iterable<PhoneNumberMatch> iterable = phoneUtil.findNumbers("+14156667777", "ZZ");

    Iterator<PhoneNumberMatch> iterator = iterable.iterator();
    try {
      iterator.remove();
      fail("Iterator must not support remove.");
    } catch (UnsupportedOperationException e) { /* success */ }

    assertTrue(iterator.hasNext());

    try {
      iterator.remove();
      fail("Iterator must not support remove.");
    } catch (UnsupportedOperationException e) { /* success */ }

    assertNotNull(iterator.next());

    try {
      iterator.remove();
      fail("Iterator must not support remove.");
    } catch (UnsupportedOperationException e) { /* success */ }

    assertFalse(iterator.hasNext());
  }

  /**
   * Asserts that another number can be found in {@code text} starting at {@code index}, and that
   * its corresponding range is {@code [start, end)}.
   */
  private void assertEqualRange(CharSequence text, int index, int start, int end) {
    CharSequence sub = text.subSequence(index, text.length());
    Iterator<PhoneNumberMatch> matches =
      phoneUtil.findNumbers(sub, "NZ", Leniency.POSSIBLE, Long.MAX_VALUE).iterator();
    assertTrue(matches.hasNext());
    PhoneNumberMatch match = matches.next();
    assertEquals(start - index, match.start());
    assertEquals(end - index, match.end());
    assertEquals(sub.subSequence(match.start(), match.end()).toString(), match.rawString());
  }

  /**
   * Tests numbers found by {@link PhoneNumberUtil#findNumbers(CharSequence, String)} in various
   * textual contexts.
   *
   * @param number the number to test and the corresponding region code to use
   */
  private void doTestFindInContext(String number, String defaultCountry) throws Exception {
    findPossibleInContext(number, defaultCountry);

    PhoneNumber parsed = phoneUtil.parse(number, defaultCountry);
    if (phoneUtil.isValidNumber(parsed)) {
      findValidInContext(number, defaultCountry);
    }
  }

  /**
   * Tests valid numbers in contexts that should pass for {@link Leniency#POSSIBLE}.
   */
  private void findPossibleInContext(String number, String defaultCountry) {
    ArrayList<NumberContext> contextPairs = new ArrayList<NumberContext>();
    contextPairs.add(new NumberContext("", ""));  // no context
    contextPairs.add(new NumberContext("   ", "\t"));  // whitespace only
    contextPairs.add(new NumberContext("Hello ", ""));  // no context at end
    contextPairs.add(new NumberContext("", " to call me!"));  // no context at start
    contextPairs.add(new NumberContext("Hi there, call ", " to reach me!"));  // no context at start
    contextPairs.add(new NumberContext("Hi there, call ", ", or don't"));  // with commas
    // Three examples without whitespace around the number.
    contextPairs.add(new NumberContext("Hi call", ""));
    contextPairs.add(new NumberContext("", "forme"));
    contextPairs.add(new NumberContext("Hi call", "forme"));
    // With other small numbers.
    contextPairs.add(new NumberContext("It's cheap! Call ", " before 6:30"));
    // With a second number later.
    contextPairs.add(new NumberContext("Call ", " or +1800-123-4567!"));
    contextPairs.add(new NumberContext("Call me on June 21 at", ""));  // with a Month-Day date
    // With publication pages.
    contextPairs.add(new NumberContext(
        "As quoted by Alfonso 12-15 (2009), you may call me at ", ""));
    contextPairs.add(new NumberContext(
        "As quoted by Alfonso et al. 12-15 (2009), you may call me at ", ""));
    // With dates, written in the American style.
    contextPairs.add(new NumberContext(
        "As I said on 03/10/2011, you may call me at ", ""));
    // With trailing numbers after a comma. The 45 should not be considered an extension.
    contextPairs.add(new NumberContext("", ", 45 days a year"));
     // With a postfix stripped off as it looks like the start of another number.
    contextPairs.add(new NumberContext("Call ", "/x12 more"));

    doTestInContext(number, defaultCountry, contextPairs, Leniency.POSSIBLE);
  }

  /**
   * Tests valid numbers in contexts that fail for {@link Leniency#POSSIBLE} but are valid for
   * {@link Leniency#VALID}.
   */
  private void findValidInContext(String number, String defaultCountry) {
    ArrayList<NumberContext> contextPairs = new ArrayList<NumberContext>();
    // With other small numbers.
    contextPairs.add(new NumberContext("It's only 9.99! Call ", " to buy"));
    // With a number Day.Month.Year date.
    contextPairs.add(new NumberContext("Call me on 21.6.1984 at ", ""));
    // With a number Month/Day date.
    contextPairs.add(new NumberContext("Call me on 06/21 at ", ""));
    // With a number Day.Month date.
    contextPairs.add(new NumberContext("Call me on 21.6. at ", ""));
    // With a number Month/Day/Year date.
    contextPairs.add(new NumberContext("Call me on 06/21/84 at ", ""));

    doTestInContext(number, defaultCountry, contextPairs, Leniency.VALID);
  }

  private void doTestInContext(String number, String defaultCountry,
      List<NumberContext> contextPairs, Leniency leniency) {
    for (NumberContext context : contextPairs) {
      String prefix = context.leadingText;
      String text = prefix + number + context.trailingText;

      int start = prefix.length();
      int end = start + number.length();
      Iterator<PhoneNumberMatch> iterator =
          phoneUtil.findNumbers(text, defaultCountry, leniency, Long.MAX_VALUE).iterator();

      PhoneNumberMatch match = iterator.hasNext() ? iterator.next() : null;
      assertNotNull("Did not find a number in '" + text + "'; expected '" + number + "'", match);

      CharSequence extracted = text.subSequence(match.start(), match.end());
      assertTrue("Unexpected phone region in '" + text + "'; extracted '" + extracted + "'",
          start == match.start() && end == match.end());
      assertTrue(number.contentEquals(extracted));
      assertTrue(match.rawString().contentEquals(extracted));

      ensureTermination(text, defaultCountry, leniency);
    }
  }

  /**
   * Exhaustively searches for phone numbers from each index within {@code text} to test that
   * finding matches always terminates.
   */
  private void ensureTermination(String text, String defaultCountry, Leniency leniency) {
    for (int index = 0; index <= text.length(); index++) {
      String sub = text.substring(index);
      StringBuilder matches = new StringBuilder();
      // Iterates over all matches.
      for (PhoneNumberMatch match :
           phoneUtil.findNumbers(sub, defaultCountry, leniency, Long.MAX_VALUE)) {
        matches.append(", ").append(match.toString());
      }
    }
  }

  private Iterator<PhoneNumberMatch> findNumbersForLeniency(
      String text, String defaultCountry, PhoneNumberUtil.Leniency leniency) {
    return phoneUtil.findNumbers(text, defaultCountry, leniency, Long.MAX_VALUE).iterator();
  }

  /**
   * Returns true if there were no matches found.
   */
  private boolean hasNoMatches(Iterator<PhoneNumberMatch> iterator) {
    return !iterator.hasNext();
  }

  private boolean hasNoMatches(Iterable<PhoneNumberMatch> iterable) {
    return !iterable.iterator().hasNext();
  }

  /**
   * Small class that holds the context of the number we are testing against. The test will
   * insert the phone number to be found between leadingText and trailingText.
   */
  private static class NumberContext {
    final String leadingText;
    final String trailingText;

    NumberContext(String leadingText, String trailingText) {
      this.leadingText = leadingText;
      this.trailingText = trailingText;
    }
  }

  /**
   * Small class that holds the number we want to test and the region for which it should be valid.
   */
  private static class NumberTest {
    final String rawString;
    final String region;

    NumberTest(String rawString, String regionCode) {
      this.rawString = rawString;
      this.region = regionCode;
    }

    @Override
    public String toString() {
      return rawString + " (" + region.toString() + ")";
    }
  }
}
