/*
 * Copyright 2007 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.tonicsystems.jarjar;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

class Wildcard {
  private static Pattern dstar = Pattern.compile("\\*\\*");
  private static Pattern star = Pattern.compile("\\*");
  private static Pattern estar = Pattern.compile("\\+\\??\\)\\Z");

  private final Pattern pattern;
  private final int count;
  private final ArrayList<Object> parts = new ArrayList<Object>(16); // kept for debugging
  private final String[] strings;
  private final int[] refs;

  public Wildcard(String pattern, String result) {
    if (pattern.equals("**")) {
      throw new IllegalArgumentException("'**' is not a valid pattern");
    }
    if (!checkIdentifierChars(pattern, "/*-")) {
      throw new IllegalArgumentException("Not a valid package pattern: " + pattern);
    }
    if (pattern.indexOf("***") >= 0) {
      throw new IllegalArgumentException("The sequence '***' is invalid in a package pattern");
    }

    String regex = pattern;
    regex = replaceAllLiteral(dstar, regex, "(.+?)");
    regex = replaceAllLiteral(star, regex, "([^/]+)");
    regex = replaceAllLiteral(estar, regex, "*)");
    this.pattern = Pattern.compile("\\A" + regex + "\\Z");
    this.count = this.pattern.matcher("foo").groupCount();

    // TODO: check for illegal characters
    char[] chars = result.toCharArray();
    int max = 0;
    for (int i = 0, mark = 0, state = 0, len = chars.length; i < len + 1; i++) {
      char ch = (i == len) ? '@' : chars[i];
      if (state == 0) {
        if (ch == '@') {
          parts.add(new String(chars, mark, i - mark));
          mark = i + 1;
          state = 1;
        }
      } else {
        switch (ch) {
          case '0':
          case '1':
          case '2':
          case '3':
          case '4':
          case '5':
          case '6':
          case '7':
          case '8':
          case '9':
            break;
          default:
            if (i == mark) {
              throw new IllegalArgumentException("Backslash not followed by a digit");
            }
            int n = Integer.parseInt(new String(chars, mark, i - mark));
            if (n > max) {
              max = n;
            }
            parts.add(new Integer(n));
            mark = i--;
            state = 0;
        }
      }
    }
    int size = parts.size();
    strings = new String[size];
    refs = new int[size];
    Arrays.fill(refs, -1);
    for (int i = 0; i < size; i++) {
      Object v = parts.get(i);
      if (v instanceof String) {
        strings[i] = ((String) v).replace('.', '/');
      } else {
        refs[i] = ((Integer) v).intValue();
      }
    }
    if (count < max) {
      throw new IllegalArgumentException(
          "Result includes impossible placeholder \"@" + max + "\": " + result);
    }
    // System.err.println(this);
  }

  public boolean matches(String value) {
    return getMatcher(value) != null;
  }

  public String replace(String value) {
    Matcher matcher = getMatcher(value);
    if (matcher != null) {
      StringBuilder sb = new StringBuilder();
      for (int i = 0; i < strings.length; i++)
        sb.append((refs[i] >= 0) ? matcher.group(refs[i]) : strings[i]);
      return sb.toString();
    }
    return null;
  }

  private Matcher getMatcher(String value) {
    Matcher matcher = pattern.matcher(value);
    if (matcher.matches() && checkIdentifierChars(value, "/-")) {
      return matcher;
    }
    return null;
  }

  private static boolean checkIdentifierChars(String expr, String extra) {
    // package-info violates the spec for Java Identifiers.
    // Nevertheless, expressions that end with this string are still legal.
    // See 7.4.1.1 of the Java language spec for discussion.
    if (expr.endsWith("package-info")) {
      expr = expr.substring(0, expr.length() - "package-info".length());
    }
    for (int i = 0, len = expr.length(); i < len; i++) {
      char c = expr.charAt(i);
      if (extra.indexOf(c) >= 0) {
        continue;
      }
      if (!Character.isJavaIdentifierPart(c)) {
        return false;
      }
    }
    return true;
  }

  private static String replaceAllLiteral(Pattern pattern, String value, String replace) {
    replace = replace.replaceAll("([$\\\\])", "\\\\$0");
    return pattern.matcher(value).replaceAll(replace);
  }

  public String toString() {
    return "Wildcard{pattern=" + pattern + ",parts=" + parts + "}";
  }
}
