/*
 * Copyright (C) 2016 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.google.copybara;

import com.google.common.base.Preconditions;
import com.google.re2j.Matcher;
import com.google.re2j.Pattern;

/**
 * A simple line finder/parser for labels like:
 * <ul>
 *   <li>foo = bar</li>
 *   <li>baz : foo</li>
 * </ul>
 *
 * <p>In general this class should only be used in {@code Origin}s to create a labels map.
 * During transformations/destination, it can be used to check if a line is a line but
 * never to find labels. Use {@link TransformWork#getLabel(String)} instead, since it looks
 * in more places for labels.
 *
 * TODO(malcon): Rename to MaybeLabel
 */
public class LabelFinder {

  private static final String VALID_LABEL_EXPR = "([\\w-]+)";

  public static final Pattern VALID_LABEL = Pattern.compile(VALID_LABEL_EXPR);

  private static final Pattern URL = Pattern.compile(VALID_LABEL + "://.*");

  private static final Pattern LABEL_PATTERN = Pattern.compile(
      "^" + VALID_LABEL_EXPR + "( *[:=] ?)(.*)");
  private final Matcher matcher;
  private final String line;

  public LabelFinder(String line) {
    matcher = LABEL_PATTERN.matcher(line);
    this.line = line;
  }

  public boolean isLabel() {
    // It is a line if it looks like a line but it doesn't look like a url (foo://bar)
    return matcher.matches() && !URL.matcher(line).matches();
  }

  public boolean isLabel(String labelName) {
    return isLabel() && getName().equals(labelName);
  }

  public String getName() {
    checkIsLabel();
    return matcher.group(1);
  }

  public String getSeparator() {
    checkIsLabel();
    return matcher.group(2);
  }

  public String getValue() {
    checkIsLabel();
    return matcher.group(3);
  }

  private void checkIsLabel() {
    Preconditions.checkState(isLabel(), "Not a label: '" + line + "'");
  }

  public String getLine() {
    return line;
  }
}

@@ -619,16 +619,80 @@
 ybara;%0A%0A
+import static com.google.common.base.Preconditions.checkState;%0A%0A
 import c
@@ -2082,174 +2082,510 @@
 %0A%0A  
-public String getName() %7B%0A    checkIsLabel();%0A    return matcher.group(1);%0A  %7D%0A%0A  public String getSeparator() %7B%0A    checkIsLabel();%0A    return matcher.group(2);%0A  %7D%0A
+/**%0A   * Returns the name of the label.%0A   *%0A   * %3Cp%3EUse isLabel() method before calling this method.%0A   */%0A  public String getName() %7B%0A    checkIsLabel();%0A    return matcher.group(1);%0A  %7D%0A%0A  /**%0A   * Returns the separator of the label.%0A   *%0A   * %3Cp%3EUse isLabel() method before calling this method.%0A   */%0A  public String getSeparator() %7B%0A    checkIsLabel();%0A    return matcher.group(2);%0A  %7D%0A%0A  /**%0A   * Returns the value of the label.%0A   *%0A   * %3Cp%3EUse isLabel() method before calling this method.%0A   */
 %0A  p
@@ -2700,30 +2700,16 @@
 ) %7B%0A    
-Preconditions.
 checkSta
@@ -2750,16 +2750,45 @@
 ine + %22'
+. Please call isLabel() first
 %22);%0A  %7D%0A

Add a clarification javadoc to LabelFinder