/*
 * Copyright (C) 2011 The Libphonenumber Authors
 *
 * 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.
 *
 * @author Shaopeng Jia
 */

package com.google.phonenumbers;

import static java.nio.charset.StandardCharsets.UTF_8;
import static java.util.Locale.ENGLISH;

import com.google.i18n.phonenumbers.AsYouTypeFormatter;
import com.google.i18n.phonenumbers.NumberParseException;
import com.google.i18n.phonenumbers.PhoneNumberToCarrierMapper;
import com.google.i18n.phonenumbers.PhoneNumberToTimeZonesMapper;
import com.google.i18n.phonenumbers.PhoneNumberUtil;
import com.google.i18n.phonenumbers.PhoneNumberUtil.PhoneNumberFormat;
import com.google.i18n.phonenumbers.PhoneNumberUtil.PhoneNumberType;
import com.google.i18n.phonenumbers.Phonenumber.PhoneNumber;
import com.google.i18n.phonenumbers.ShortNumberInfo;
import com.google.i18n.phonenumbers.geocoding.PhoneNumberOfflineGeocoder;

import org.apache.commons.fileupload.FileItemIterator;
import org.apache.commons.fileupload.FileItemStream;
import org.apache.commons.fileupload.FileUploadException;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import org.apache.commons.fileupload.util.Streams;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang.StringEscapeUtils;

import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.Locale;
import java.util.StringTokenizer;

import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * A servlet that accepts requests that contain strings representing a phone number and a default
 * country, and responds with results from parsing, validating and formatting the number. The
 * default country is a two-letter region code representing the country that we are expecting the
 * number to be from.
 */
@SuppressWarnings("serial")
public class PhoneNumberParserServlet extends HttpServlet {
  private PhoneNumberUtil phoneUtil = PhoneNumberUtil.getInstance();
  private ShortNumberInfo shortInfo = ShortNumberInfo.getInstance();
  public void doPost(HttpServletRequest req, HttpServletResponse resp) throws IOException {
    String phoneNumber = null;
    String defaultCountry = null;
    String languageCode = "en";  // Default languageCode to English if nothing is entered.
    String regionCode = "";
    String fileContents = null;
    ServletFileUpload upload = new ServletFileUpload();
    upload.setSizeMax(50000);
    try {
      FileItemIterator iterator = upload.getItemIterator(req);
      while (iterator.hasNext()) {
        FileItemStream item = iterator.next();
        InputStream in = item.openStream();
        if (item.isFormField()) {
          String fieldName = item.getFieldName();
          if (fieldName.equals("phoneNumber")) {
            phoneNumber = Streams.asString(in, UTF_8.name());
          } else if (fieldName.equals("defaultCountry")) {
            defaultCountry = Streams.asString(in).toUpperCase();
          } else if (fieldName.equals("languageCode")) {
            String languageEntered = Streams.asString(in).toLowerCase();
            if (languageEntered.length() > 0) {
              languageCode = languageEntered;
            }
          } else if (fieldName.equals("regionCode")) {
            regionCode = Streams.asString(in).toUpperCase();
          }
        } else {
          try {
            fileContents = IOUtils.toString(in);
          } finally {
            IOUtils.closeQuietly(in);
          }
        }
      }
    } catch (FileUploadException e1) {
      e1.printStackTrace();
    }

    StringBuilder output;
    resp.setContentType("text/html");
    resp.setCharacterEncoding(UTF_8.name());
    if (fileContents == null || fileContents.length() == 0) {
      // Redirect to a URL with the given input encoded in the query parameters.
      Locale geocodingLocale = new Locale(languageCode, regionCode);
      resp.sendRedirect(getPermaLinkURL(phoneNumber, defaultCountry, geocodingLocale,
          false /* absoluteURL */));
    } else {
      resp.getWriter().println(getOutputForFile(defaultCountry, fileContents));
    }
  }

  /**
   * Handle the get request to get information about a number based on query parameters.
   */
  public void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException {
    String phoneNumber = req.getParameter("number");
    if (phoneNumber == null) {
      phoneNumber = "";
    }
    String defaultCountry = req.getParameter("country");
    if (defaultCountry == null) {
      defaultCountry = "";
    }
    String geocodingParam = req.getParameter("geocodingLocale");
    Locale geocodingLocale;
    if (geocodingParam == null) {
      geocodingLocale = ENGLISH;  // Default languageCode to English if nothing is entered.
    } else {
      geocodingLocale = Locale.forLanguageTag(geocodingParam);
    }
    resp.setContentType("text/html");
    resp.setCharacterEncoding(UTF_8.name());
    resp.getWriter().println(
        getOutputForSingleNumber(phoneNumber, defaultCountry, geocodingLocale));
  }

  private StringBuilder getOutputForFile(String defaultCountry, String fileContents) {
    StringBuilder output = new StringBuilder(
        "<HTML><HEAD><TITLE>Results generated from phone numbers in the file provided:"
        + "</TITLE></HEAD><BODY>");
    output.append("<TABLE align=center border=1>");
    output.append("<TH align=center>ID</TH>");
    output.append("<TH align=center>Raw phone number</TH>");
    output.append("<TH align=center>Pretty formatting</TH>");
    output.append("<TH align=center>International format</TH>");

    int phoneNumberId = 0;
    StringTokenizer tokenizer = new StringTokenizer(fileContents, ",");
    while (tokenizer.hasMoreTokens()) {
      String numberStr = tokenizer.nextToken();
      phoneNumberId++;
      output.append("<TR>");
      output.append("<TD align=center>").append(phoneNumberId).append(" </TD> \n");
      output.append("<TD align=center>").append(
          StringEscapeUtils.escapeHtml(numberStr)).append(" </TD> \n");
      try {
        PhoneNumber number = phoneUtil.parseAndKeepRawInput(numberStr, defaultCountry);
        boolean isNumberValid = phoneUtil.isValidNumber(number);
        String prettyFormat = isNumberValid
            ? phoneUtil.formatInOriginalFormat(number, defaultCountry)
            : "invalid";
        String internationalFormat = isNumberValid
            ? phoneUtil.format(number, PhoneNumberFormat.INTERNATIONAL)
            : "invalid";

        output.append("<TD align=center>").append(
            StringEscapeUtils.escapeHtml(prettyFormat)).append(" </TD> \n");
        output.append("<TD align=center>").append(
            StringEscapeUtils.escapeHtml(internationalFormat)).append(" </TD> \n");
      } catch (NumberParseException e) {
        output.append("<TD align=center colspan=2>").append(
            StringEscapeUtils.escapeHtml(e.toString())).append(" </TD> \n");
      }
      output.append("</TR>");
    }
    output.append("</BODY></HTML>");
    return output;
  }

  private void appendLine(String title, String data, StringBuilder output) {
    output.append("<TR>");
    output.append("<TH>").append(title).append("</TH>");
    output.append("<TD>").append(data.length() > 0 ? data : "&nbsp;").append("</TD>");
    output.append("</TR>");
  }

  /**
   * Returns a stable URL pointing to the result page for the given input.
   */
  private String getPermaLinkURL(
      String phoneNumber, String defaultCountry, Locale geocodingLocale, boolean absoluteURL) {
    // If absoluteURL is false, generate a relative path. Otherwise, produce an absolute URL.
    StringBuilder permaLink = new StringBuilder(
        absoluteURL ? "http://libphonenumber.appspot.com/phonenumberparser" : "/phonenumberparser");
    try {
      permaLink.append(
          "?number=" + URLEncoder.encode(phoneNumber != null ? phoneNumber : "", UTF_8.name()));
      if (defaultCountry != null && !defaultCountry.isEmpty()) {
        permaLink.append("&country=" + URLEncoder.encode(defaultCountry, UTF_8.name()));
      }
      if (!geocodingLocale.getLanguage().equals(ENGLISH.getLanguage()) ||
          !geocodingLocale.getCountry().isEmpty()) {
        permaLink.append("&geocodingLocale=" +
            URLEncoder.encode(geocodingLocale.toLanguageTag(), UTF_8.name()));
      }
    } catch(UnsupportedEncodingException e) {
      // UTF-8 is guaranteed in Java, so this should be impossible.
      throw new AssertionError(e);
    }
    return permaLink.toString();
  }

  /**
   * Returns a link to create a new github issue with the relevant information.
   */
  private String getNewIssueLink(
      String phoneNumber, String defaultCountry, Locale geocodingLocale) {
    boolean hasDefaultCountry = !defaultCountry.isEmpty() && defaultCountry != "ZZ";
    String issueTitle = "Validation issue with " + phoneNumber
        + (hasDefaultCountry ? " (" + defaultCountry + ")" : "");

    // Issue template. This must be kept in sync with the template in
    // https://github.com/googlei18n/libphonenumber/blob/master/CONTRIBUTING.md.
    StringBuilder issueTemplate = new StringBuilder(
        "Please read the \"guidelines for contributing\" (linked above) and fill "
        + "in the template below.\n\n");
    issueTemplate.append("Country/region affected (e.g., \"US\"): ")
        .append(defaultCountry).append("\n\n");
    issueTemplate.append("Example number(s) affected (\"+1 555 555-1234\"): ")
        .append(phoneNumber).append("\n\n");
    issueTemplate.append(
        "The phone number range(s) to which the issue applies (\"+1 555 555-XXXX\"): \n\n");
    issueTemplate.append(
        "The type of the number(s) (\"fixed-line\", \"mobile\", \"short code\", etc.): \n\n");
    issueTemplate.append(
        "The cost, if applicable (\"toll-free\", \"premium rate\", \"shared cost\"): \n\n");
    issueTemplate.append(
        "Supporting evidence (for example, national numbering plan, announcement from mobile "
        + "carrier, news article): **IMPORTANT - anything posted here is made public. "
        + "Read the guidelines first!** \n\n");
    issueTemplate.append("[link to demo]("
        + getPermaLinkURL(phoneNumber, defaultCountry, geocodingLocale, true /* absoluteURL */)
        + ")\n\n");
    String newIssueLink = "https://github.com/googlei18n/libphonenumber/issues/new?title=";
    try {
      newIssueLink += URLEncoder.encode(issueTitle, UTF_8.name()) + "&body="
        + URLEncoder.encode(issueTemplate.toString(), UTF_8.name());
    } catch(UnsupportedEncodingException e) {
      // UTF-8 is guaranteed in Java, so this should be impossible.
      throw new AssertionError(e);
    }
    return newIssueLink;
  }

  /**
   * The defaultCountry here is used for parsing phoneNumber. The geocodingLocale is used to specify
   * the language used for displaying the area descriptions generated from phone number geocoding.
   */
  private StringBuilder getOutputForSingleNumber(
      String phoneNumber, String defaultCountry, Locale geocodingLocale) {
    StringBuilder output = new StringBuilder("<HTML><HEAD>");
    output.append(
        "<LINK type=\"text/css\" rel=\"stylesheet\" href=\"/stylesheets/main.css\" />");
    output.append("</HEAD>");
    output.append("<BODY>");
    output.append("Phone Number entered: " + StringEscapeUtils.escapeHtml(phoneNumber) + "<BR>");
    output.append("defaultCountry entered: " + StringEscapeUtils.escapeHtml(defaultCountry)
        + "<BR>");
    output.append("Language entered: "
        + StringEscapeUtils.escapeHtml(geocodingLocale.toLanguageTag()) + "<BR>");
    try {
      PhoneNumber number = phoneUtil.parseAndKeepRawInput(phoneNumber, defaultCountry);
      output.append("<DIV>");
      output.append("<TABLE border=1>");
      output.append("<TR><TD colspan=2>Parsing Result (parseAndKeepRawInput())</TD></TR>");

      appendLine("country_code", Integer.toString(number.getCountryCode()), output);
      appendLine("national_number", Long.toString(number.getNationalNumber()), output);
      appendLine("extension", number.getExtension(), output);
      appendLine("country_code_source", number.getCountryCodeSource().toString(), output);
      appendLine("italian_leading_zero", Boolean.toString(number.isItalianLeadingZero()), output);
      appendLine("raw_input", number.getRawInput(), output);
      output.append("</TABLE>");
      output.append("</DIV>");

      boolean isPossible = phoneUtil.isPossibleNumber(number);
      boolean isNumberValid = phoneUtil.isValidNumber(number);
      PhoneNumberType numberType = phoneUtil.getNumberType(number);
      boolean hasDefaultCountry = !defaultCountry.isEmpty() && defaultCountry != "ZZ";

      output.append("<DIV>");
      output.append("<TABLE border=1>");
      output.append("<TR><TD colspan=2>Validation Results</TD></TR>");
      appendLine("Result from isPossibleNumber()", Boolean.toString(isPossible), output);
      if (!isPossible) {
        appendLine("Result from isPossibleNumberWithReason()",
                   phoneUtil.isPossibleNumberWithReason(number).toString(), output);
        output.append("<TR><TD colspan=2>Note: numbers that are not possible have type " +
                      "UNKNOWN, an unknown region, and are considered invalid.</TD></TR>");
      } else {
        appendLine("Result from isValidNumber()", Boolean.toString(isNumberValid), output);
        if (isNumberValid) {
          if (hasDefaultCountry) {
            appendLine(
                "Result from isValidNumberForRegion()",
                Boolean.toString(phoneUtil.isValidNumberForRegion(number, defaultCountry)),
                output);
          }
        }
        String region = phoneUtil.getRegionCodeForNumber(number);
        appendLine("Phone Number region", region == null ? "" : region, output);
        appendLine("Result from getNumberType()", numberType.toString(), output);
      }
      output.append("</TABLE>");
      output.append("</DIV>");

      if (!isNumberValid) {
        output.append("<DIV>");
        output.append("<TABLE border=1>");
        output.append("<TR><TD colspan=2>Short Number Results</TD></TR>");
        boolean isPossibleShort = shortInfo.isPossibleShortNumber(number);
        appendLine("Result from isPossibleShortNumber()",
            Boolean.toString(isPossibleShort), output);
        if (isPossibleShort) {
          appendLine("Result from isValidShortNumber()",
              Boolean.toString(shortInfo.isValidShortNumber(number)), output);
          if (hasDefaultCountry) {
            boolean isPossibleShortForRegion =
                shortInfo.isPossibleShortNumberForRegion(number, defaultCountry);
            appendLine("Result from isPossibleShortNumberForRegion()",
                Boolean.toString(isPossibleShortForRegion), output);
            if (isPossibleShortForRegion) {
              appendLine("Result from isValidShortNumberForRegion()",
                  Boolean.toString(shortInfo.isValidShortNumberForRegion(number,
                      defaultCountry)), output);
            }
          }
        }
        output.append("</TABLE>");
        output.append("</DIV>");
      }

      output.append("<DIV>");
      output.append("<TABLE border=1>");
      output.append("<TR><TD colspan=2>Formatting Results</TD></TR>");
      appendLine("E164 format",
                 isNumberValid ? phoneUtil.format(number, PhoneNumberFormat.E164) : "invalid",
                 output);
      appendLine("Original format",
                 phoneUtil.formatInOriginalFormat(number, defaultCountry), output);
      appendLine("National format", phoneUtil.format(number, PhoneNumberFormat.NATIONAL), output);
      appendLine(
          "International format",
          isNumberValid ? phoneUtil.format(number, PhoneNumberFormat.INTERNATIONAL) : "invalid",
          output);
      appendLine(
          "Out-of-country format from US",
          isNumberValid ? phoneUtil.formatOutOfCountryCallingNumber(number, "US") : "invalid",
          output);
      appendLine(
          "Out-of-country format from CH",
          isNumberValid ? phoneUtil.formatOutOfCountryCallingNumber(number, "CH") : "invalid",
          output);
      output.append("</TABLE>");
      output.append("</DIV>");

      AsYouTypeFormatter formatter = phoneUtil.getAsYouTypeFormatter(defaultCountry);
      int rawNumberLength = phoneNumber.length();
      output.append("<DIV>");
      output.append("<TABLE border=1>");
      output.append("<TR><TD colspan=2>AsYouTypeFormatter Results</TD></TR>");
      for (int i = 0; i < rawNumberLength; i++) {
        // Note this doesn't handle supplementary characters, but it shouldn't be a big deal as
        // there are no dial-pad characters in the supplementary range.
        char inputChar = phoneNumber.charAt(i);
        appendLine("Char entered: '" + inputChar + "' Output: ",
                   formatter.inputDigit(inputChar), output);
      }
      output.append("</TABLE>");
      output.append("</DIV>");

      if (isNumberValid) {
        output.append("<DIV>");
        output.append("<TABLE border=1>");
        output.append("<TR><TD colspan=2>PhoneNumberOfflineGeocoder Results</TD></TR>");
        appendLine(
            "Location",
            PhoneNumberOfflineGeocoder.getInstance().getDescriptionForNumber(
                number, geocodingLocale),
            output);
        output.append("</TABLE>");
        output.append("</DIV>");

        output.append("<DIV>");
        output.append("<TABLE border=1>");
        output.append("<TR><TD colspan=2>PhoneNumberToTimeZonesMapper Results</TD></TR>");
        appendLine(
            "Time zone(s)",
            PhoneNumberToTimeZonesMapper.getInstance().getTimeZonesForNumber(number).toString(),
            output);
        output.append("</TABLE>");
        output.append("</DIV>");

        if (numberType == PhoneNumberType.MOBILE ||
            numberType == PhoneNumberType.FIXED_LINE_OR_MOBILE ||
            numberType == PhoneNumberType.PAGER) {
          output.append("<DIV>");
          output.append("<TABLE border=1>");
          output.append("<TR><TD colspan=2>PhoneNumberToCarrierMapper Results</TD></TR>");
          appendLine(
              "Carrier",
              PhoneNumberToCarrierMapper.getInstance().getNameForNumber(number, geocodingLocale),
              output);
          output.append("</TABLE>");
          output.append("</DIV>");
        }
      }

      String newIssueLink = getNewIssueLink(phoneNumber, defaultCountry, geocodingLocale);
      String guidelinesLink =
          "https://github.com/googlei18n/libphonenumber/blob/master/CONTRIBUTING.md";
      output.append("<b style=\"color:red\">File an issue</b>: by clicking on "
          + "<a target=\"_blank\" href=\"" + newIssueLink + "\">this link</a>, I confirm that I "
          + "have read the <a target=\"_blank\" href=\"" + guidelinesLink
          + "\">contributor's guidelines</a>.");
    } catch (NumberParseException e) {
      output.append(StringEscapeUtils.escapeHtml(e.toString()));
    }
    output.append("</BODY></HTML>");
    return output;
  }
}
