// Copyright (C) 2020 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 com.google.gerrit.plugins.codeowners.backend.findowners;

import static com.google.common.base.Preconditions.checkState;
import static com.google.common.collect.ImmutableList.toImmutableList;
import static com.google.common.collect.ImmutableSet.toImmutableSet;
import static com.google.common.collect.ImmutableSortedSet.toImmutableSortedSet;
import static java.util.Comparator.naturalOrder;
import static java.util.Objects.requireNonNull;
import static java.util.stream.Collectors.joining;

import com.google.common.annotations.VisibleForTesting;
import com.google.common.base.Joiner;
import com.google.common.base.Splitter;
import com.google.common.base.Strings;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.ListMultimap;
import com.google.common.collect.MultimapBuilder;
import com.google.common.collect.SortedSetMultimap;
import com.google.common.collect.TreeMultimap;
import com.google.gerrit.entities.Project;
import com.google.gerrit.plugins.codeowners.backend.CodeOwnerAnnotation;
import com.google.gerrit.plugins.codeowners.backend.CodeOwnerConfig;
import com.google.gerrit.plugins.codeowners.backend.CodeOwnerConfigImportMode;
import com.google.gerrit.plugins.codeowners.backend.CodeOwnerConfigParseException;
import com.google.gerrit.plugins.codeowners.backend.CodeOwnerConfigParser;
import com.google.gerrit.plugins.codeowners.backend.CodeOwnerConfigReference;
import com.google.gerrit.plugins.codeowners.backend.CodeOwnerReference;
import com.google.gerrit.plugins.codeowners.backend.CodeOwnerSet;
import com.google.gerrit.server.git.ValidationError;
import com.google.inject.Singleton;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.SortedSet;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Stream;
import org.eclipse.jgit.lib.ObjectId;

/**
 * Parser and formatter for the syntax that is used to store {@link CodeOwnerConfig}s in {@code
 * OWNERS} files as they are used by the {@code find-owners} plugin.
 *
 * <p>The syntax is described at in the {@code find-owners} plugin documentation at:
 * https://gerrit.googlesource.com/plugins/find-owners/+/HEAD/src/main/resources/Documentation/syntax.md
 *
 * <p>Comment lines are silently ignored.
 *
 * <p>Invalid lines cause the parsing to fail and trigger a {@link CodeOwnerConfigParseException}.
 *
 * <p>Comments can appear as separate lines and as appendix for email lines (e.g. using
 * 'foo.bar@example.com # Foo Bar' would be a valid email line).
 *
 * <p>Most of the code in this class was copied from the {@code
 * com.googlesource.gerrit.plugins.findowners.Parser} class from the {@code find-owners} plugin. The
 * original parsing code is used to be as backwards-compatible as possible and to avoid spending
 * time on reimplementing a parser for a deprecated syntax. We have only done a minimal amount of
 * adaption so that the parser produces a {@link CodeOwnerConfig} as result, instead of the
 * abstraction that is used in the {@code find-owners} plugin.
 */
@Singleton
@VisibleForTesting
public class FindOwnersCodeOwnerConfigParser implements CodeOwnerConfigParser {
  // Artifical owner token for "set noparent" when used in per-file.
  private static final String TOK_SET_NOPARENT = "set noparent";

  /**
   * Any Unicode linebreak sequence, is equivalent to {@code
   * \u000D\u000A|[\u000A\u000B\u000C\u000D\u0085\u2028\u2029]}.
   */
  private static final String LINEBREAK_MATCHER = "\\R";

  @Override
  public CodeOwnerConfig parse(
      ObjectId revision, CodeOwnerConfig.Key codeOwnerConfigKey, String codeOwnerConfigAsString)
      throws CodeOwnerConfigParseException {
    requireNonNull(revision, "revision");
    requireNonNull(codeOwnerConfigKey, "codeOwnerConfigKey");

    Parser parser = new Parser();
    CodeOwnerConfig codeOwnerConfig =
        parser.parse(revision, codeOwnerConfigKey, Strings.nullToEmpty(codeOwnerConfigAsString));
    if (!parser.getValidationErrors().isEmpty()) {
      throw new CodeOwnerConfigParseException(codeOwnerConfigKey, parser.getValidationErrors());
    }
    return codeOwnerConfig;
  }

  @Override
  public String formatAsString(CodeOwnerConfig codeOwnerConfig) {
    return Formatter.formatAsString(requireNonNull(codeOwnerConfig, "codeOwnerConfig"));
  }

  public static String replaceEmail(
      String codeOwnerConfigFileContent, String oldEmail, String newEmail) {
    requireNonNull(codeOwnerConfigFileContent, "codeOwnerConfigFileContent");
    requireNonNull(oldEmail, "oldEmail");
    requireNonNull(newEmail, "newEmail");

    String charsThatCanAppearBeforeOrAfterEmail = "[\\s=,#]";
    Pattern pattern =
        Pattern.compile(
            "(^|.*"
                + charsThatCanAppearBeforeOrAfterEmail
                + "+)"
                + "("
                + Pattern.quote(oldEmail)
                + ")"
                + "($|"
                + charsThatCanAppearBeforeOrAfterEmail
                + "+.*)");

    List<String> updatedLines = new ArrayList<>();
    for (String line : Splitter.onPattern(LINEBREAK_MATCHER).split(codeOwnerConfigFileContent)) {
      while (pattern.matcher(line).matches()) {
        line = pattern.matcher(line).replaceFirst("$1" + newEmail + "$3");
      }
      updatedLines.add(line);
    }
    return Joiner.on("\n").join(updatedLines);
  }

  @VisibleForTesting
  static class Parser implements ValidationError.Sink {
    private static final String COMMA = "[\\s]*,[\\s]*";

    // Separator for project and file paths in an include line.
    private static final String COLON = "[\\s]*:[\\s]*"; // project:file

    private static final String BOL = "^[\\s]*"; // begin-of-line
    private static final String EOL = "[\\s]*(#.*)?$"; // end-of-line
    private static final String GLOB = "[^\\s,=]+"; // a file glob

    private static final String EMAIL_OR_STAR = "([^\\s<>@,]+@[^\\s<>@#,]+|\\*)";
    private static final String EMAIL_LIST =
        "(" + EMAIL_OR_STAR + "(" + COMMA + EMAIL_OR_STAR + ")*)";

    // Optional name of a Gerrit project followed by a colon and optional spaces.
    private static final String PROJECT_NAME = "([^\\s:]+" + COLON + ")?";

    // Optional name of a branch followed by a colon and optional spaces.
    private static final String BRANCH_NAME = "([^\\s:]+" + COLON + ")?";

    // A relative or absolute file path name without any colon or space character.
    private static final String FILE_PATH = "([^\\s:#]+)";

    private static final String PROJECT_BRANCH_AND_FILE = PROJECT_NAME + BRANCH_NAME + FILE_PATH;

    private static final String SET_NOPARENT = "set[\\s]+noparent";

    private static final String FILE_DIRECTIVE = "file:[\\s]*" + PROJECT_BRANCH_AND_FILE;
    private static final String INCLUDE_DIRECTIVE = "include[\\s]+" + PROJECT_BRANCH_AND_FILE;
    private static final String INCLUDE_OR_FILE = "(file:[\\s]*|include[\\s]+)";

    // Simple input lines with 0 or 1 sub-pattern.
    private static final Pattern PAT_COMMENT = Pattern.compile(BOL + EOL);
    private static final Pattern PAT_EMAIL = Pattern.compile(BOL + EMAIL_OR_STAR + EOL);
    private static final Pattern PAT_ANNOTATION = Pattern.compile("#\\{([A-Za-z_]+)\\}");
    private static final Pattern PAT_INCLUDE =
        Pattern.compile(BOL + INCLUDE_OR_FILE + PROJECT_BRANCH_AND_FILE + EOL);
    private static final Pattern PAT_NO_PARENT = Pattern.compile(BOL + SET_NOPARENT + EOL);

    private static final Pattern PAT_PER_FILE_OWNERS =
        Pattern.compile("^(" + EMAIL_LIST + "|" + SET_NOPARENT + "|" + FILE_DIRECTIVE + ")$");
    private static final Pattern PAT_PER_FILE_INCLUDE =
        Pattern.compile("^(" + INCLUDE_DIRECTIVE + ")$");
    private static final Pattern PAT_GLOBS =
        Pattern.compile("^(" + GLOB + "(" + COMMA + GLOB + ")*)$");

    // PAT_PER_FILE matches a line to two groups: (1) globs, (2) emails
    // Trimmed 1st group should match PAT_GLOBS;
    // trimmed 2nd group should match PAT_PER_FILE_OWNERS.
    private static final Pattern PAT_PER_FILE =
        Pattern.compile(BOL + "per-file[\\s]+([^=#]+)=[\\s]*([^#]+)" + EOL);

    private ImmutableList.Builder<ValidationError> validationErrors;

    CodeOwnerConfig parse(
        ObjectId revision, CodeOwnerConfig.Key codeOwnerConfigKey, String codeOwnerConfigAsString) {
      CodeOwnerConfig.Builder codeOwnerConfigBuilder =
          CodeOwnerConfig.builder(codeOwnerConfigKey, revision);
      CodeOwnerSet.Builder globalCodeOwnerSetBuilder = CodeOwnerSet.builder();
      List<CodeOwnerSet> perFileCodeOwnerSet = new ArrayList<>();

      for (String line : Splitter.onPattern(LINEBREAK_MATCHER).split(codeOwnerConfigAsString)) {
        parseLine(codeOwnerConfigBuilder, globalCodeOwnerSetBuilder, perFileCodeOwnerSet, line);
      }

      // Make the code owners sets with the global code owners the first one in the list.
      CodeOwnerSet globalCodeOwnersSet = globalCodeOwnerSetBuilder.build();
      if (!globalCodeOwnersSet.codeOwners().isEmpty()) {
        codeOwnerConfigBuilder.addCodeOwnerSet(globalCodeOwnersSet);
      }
      perFileCodeOwnerSet.forEach(codeOwnerConfigBuilder::addCodeOwnerSet);

      return codeOwnerConfigBuilder.build();
    }

    private void parseLine(
        CodeOwnerConfig.Builder codeOwnerConfigBuilder,
        CodeOwnerSet.Builder globalCodeOwnerSetBuilder,
        List<CodeOwnerSet> perFileCodeOwnerSets,
        String line) {
      ParsedEmailLine parsedEmailLine;
      CodeOwnerSet codeOwnerSet;
      CodeOwnerConfigReference codeOwnerConfigReference;
      if (isNoParent(line)) {
        codeOwnerConfigBuilder.setIgnoreParentCodeOwners();
      } else if (isComment(line)) {
        // ignore comment lines and empty lines
      } else if ((parsedEmailLine = parseEmailLine(line)) != null) {
        globalCodeOwnerSetBuilder.addCodeOwner(parsedEmailLine.codeOwnerReference());
        globalCodeOwnerSetBuilder.addAnnotations(
            parsedEmailLine.codeOwnerReference(), parsedEmailLine.annotations());
      } else if ((codeOwnerSet = parsePerFileLine(line)) != null) {
        perFileCodeOwnerSets.add(codeOwnerSet);
      } else if ((codeOwnerConfigReference = parseInclude(line)) != null) {
        codeOwnerConfigBuilder.addImport(codeOwnerConfigReference);
      } else {
        error(ValidationError.create(String.format("invalid line: %s", line)));
      }
    }

    private CodeOwnerSet parsePerFileLine(String line) {
      Matcher perFileMatcher = PAT_PER_FILE.matcher(line);
      if (!perFileMatcher.matches() || !isGlobs(perFileMatcher.group(1).trim())) {
        return null;
      }

      String matchedGroup2 = perFileMatcher.group(2).trim();
      if (!PAT_PER_FILE_OWNERS.matcher(matchedGroup2).matches()) {
        if (PAT_PER_FILE_INCLUDE.matcher(matchedGroup2).matches()) {
          error(
              ValidationError.create(
                  String.format(
                      "keyword 'include' is not supported for per file imports: %s", line)));

          // return an empty code owner set to avoid that the line will be reported as invalid once
          // more
          return CodeOwnerSet.builder().build();
        }
        return null;
      }

      String[] globsAndOwners =
          new String[] {
            removeExtraSpaces(perFileMatcher.group(1)), removeExtraSpaces(perFileMatcher.group(2))
          };
      ImmutableSet<String> dirGlobs = splitGlobs(globsAndOwners[0]);
      String directive = globsAndOwners[1];
      if (directive.equals(TOK_SET_NOPARENT)) {
        return CodeOwnerSet.builder()
            .setIgnoreGlobalAndParentCodeOwners()
            .setPathExpressions(dirGlobs)
            .build();
      }

      CodeOwnerConfigReference codeOwnerConfigReference;
      if ((codeOwnerConfigReference = parseInclude(directive)) != null) {
        return CodeOwnerSet.builder()
            .addImport(codeOwnerConfigReference)
            .setPathExpressions(dirGlobs)
            .build();
      }

      List<String> ownerEmails = Arrays.asList(directive.split(COMMA, -1));

      // Get the comment part of the line (the first '#' and everything that follows).
      String comment = perFileMatcher.group(3);
      Set<CodeOwnerAnnotation> annotations = new HashSet<>();
      if (comment != null) {
        Matcher annotationMatcher = PAT_ANNOTATION.matcher(comment);
        while (annotationMatcher.find()) {
          String annotation = annotationMatcher.group(1);
          annotations.add(CodeOwnerAnnotation.create(annotation));
        }
      }

      CodeOwnerSet.Builder codeOwnerSet =
          CodeOwnerSet.builder()
              .setPathExpressions(dirGlobs)
              .setCodeOwners(
                  ownerEmails.stream().map(CodeOwnerReference::create).collect(toImmutableSet()));
      ownerEmails.stream()
          .forEach(
              email -> codeOwnerSet.addAnnotations(CodeOwnerReference.create(email), annotations));
      return codeOwnerSet.build();
    }

    /**
     * Splits the given glob string by the commas that separate the globs.
     *
     * <p>Commas that appear within a glob do not cause the string to be split at this position:
     *
     * <ul>
     *   <li>commas that are used as separator when matching choices via {@code {choice1,choice2}}
     *   <li>commas that appears as part of a character class via {@code
     *       [<any-chars-including-comma>]}
     * </ul>
     *
     * @param commaSeparatedGlobs globs as comma-separated list
     * @return the globs as array
     */
    @VisibleForTesting
    static ImmutableSet<String> splitGlobs(String commaSeparatedGlobs) {
      ImmutableSet.Builder<String> globList = ImmutableSet.builder();
      StringBuilder nextGlob = new StringBuilder();
      int curlyBracesIndentionLevel = 0;
      int squareBracesIndentionLevel = 0;
      for (int i = 0; i < commaSeparatedGlobs.length(); i++) {
        char c = commaSeparatedGlobs.charAt(i);
        if (c == ',') {
          if (curlyBracesIndentionLevel == 0 && squareBracesIndentionLevel == 0) {
            globList.add(nextGlob.toString());
            nextGlob = new StringBuilder();
          } else {
            nextGlob.append(c);
          }
        } else {
          nextGlob.append(c);
          if (c == '{') {
            curlyBracesIndentionLevel++;
          } else if (c == '}') {
            if (curlyBracesIndentionLevel > 0) {
              curlyBracesIndentionLevel--;
            }
          } else if (c == '[') {
            squareBracesIndentionLevel++;
          } else if (c == ']') {
            if (squareBracesIndentionLevel > 0) {
              squareBracesIndentionLevel--;
            }
          }
        }
      }
      if (nextGlob.length() > 0) {
        globList.add(nextGlob.toString());
      }
      return globList.build();
    }

    private static boolean isComment(String line) {
      return PAT_COMMENT.matcher(line).matches();
    }

    private static boolean isNoParent(String line) {
      return PAT_NO_PARENT.matcher(line).matches();
    }

    private static ParsedEmailLine parseEmailLine(String line) {
      Matcher emailMatcher = PAT_EMAIL.matcher(line);
      if (!emailMatcher.matches()) {
        return null;
      }
      String email = emailMatcher.group(1).trim();
      ParsedEmailLine.Builder parsedEmailLine = ParsedEmailLine.builder(email);

      // Get the comment part of the line (the first '#' and everything that follows).
      String comment = emailMatcher.group(2);
      if (comment != null) {
        Matcher annotationMatcher = PAT_ANNOTATION.matcher(comment);
        while (annotationMatcher.find()) {
          String annotation = annotationMatcher.group(1);
          parsedEmailLine.addAnnotation(annotation);
        }
      }

      return parsedEmailLine.build();
    }

    private static CodeOwnerConfigReference parseInclude(String line) {
      Matcher m = Parser.PAT_INCLUDE.matcher(line);
      if (!m.matches()) {
        return null;
      }

      String keyword = m.group(1).trim();
      CodeOwnerConfigImportMode importMode =
          keyword.equals("include")
              ? CodeOwnerConfigImportMode.ALL
              : CodeOwnerConfigImportMode.GLOBAL_CODE_OWNER_SETS_ONLY;

      CodeOwnerConfigReference.Builder builder =
          CodeOwnerConfigReference.builder(importMode, m.group(4).trim());

      String projectName = m.group(2);
      if (projectName != null && projectName.length() > 1) {
        // PROJECT_NAME ends with ':'
        projectName = projectName.split(COLON, -1)[0].trim();
        builder.setProject(Project.nameKey(projectName));

        String branchName = m.group(3);
        if (branchName != null && branchName.length() > 1) {
          // BRANCH_NAME ends with ':'
          branchName = branchName.split(COLON, -1)[0].trim();
          builder.setBranch(branchName);
        }
      }

      return builder.build();
    }

    private static boolean isGlobs(String line) {
      return PAT_GLOBS.matcher(line).matches();
    }

    private static String removeExtraSpaces(String s) {
      return s.trim().replaceAll("[\\s]+", " ").replaceAll("[\\s]*:[\\s]*", ":");
    }

    /**
     * Get the validation errors, if any were discovered during parsing the code owner config file.
     *
     * @return list of errors; empty list if there are no errors.
     */
    public ImmutableList<ValidationError> getValidationErrors() {
      if (validationErrors != null) {
        return validationErrors.build();
      }
      return ImmutableList.of();
    }

    @Override
    public void error(ValidationError error) {
      if (validationErrors == null) {
        validationErrors = ImmutableList.builder();
      }
      validationErrors.add(error);
    }
  }

  private static class Formatter {
    private static final String SET_NOPARENT_LINE = "set noparent\n";

    // String format for a "per-file" line. The first placeholder is for the comma-separated list of
    // path expressions, the second placeholder is for the comma-separated list of emails.
    private static final String PER_FILE_LINE_FORMAT = "per-file %s=%s\n";

    static String formatAsString(CodeOwnerConfig codeOwnerConfig) {
      return formatIgnoreParentCodeOwners(codeOwnerConfig)
          + formatImports(codeOwnerConfig)
          + formatFolderCodeOwners(codeOwnerConfig)
          + formatPerFileCodeOwners(codeOwnerConfig);
    }

    private static String formatIgnoreParentCodeOwners(CodeOwnerConfig codeOwnerConfig) {
      return codeOwnerConfig.ignoreParentCodeOwners() ? SET_NOPARENT_LINE : "";
    }

    private static String formatFolderCodeOwners(CodeOwnerConfig codeOwnerConfig) {
      ImmutableSet<CodeOwnerSet> folderCodeOwnerSets =
          codeOwnerConfig.codeOwnerSets().stream()
              // Filter out code owner sets with path expressions. If path expressions are present
              // the code owner set defines per-file code owners and is handled in
              // formatPerFileCodeOwners(CodeOwnerConfig).
              .filter(codeOwnerSet -> codeOwnerSet.pathExpressions().isEmpty())
              .collect(toImmutableSet());
      ImmutableList<String> emails =
          folderCodeOwnerSets.stream()
              .flatMap(codeOwnerSet -> codeOwnerSet.codeOwners().stream())
              .map(CodeOwnerReference::email)
              .sorted()
              .distinct()
              .collect(toImmutableList());
      SortedSetMultimap<String, String> annotations = TreeMultimap.create();
      folderCodeOwnerSets.forEach(
          codeOwnerSet ->
              codeOwnerSet
                  .annotations()
                  .forEach(
                      (codeOwnerReference, annotation) ->
                          annotations.put(codeOwnerReference.email(), annotation.key())));

      StringBuilder b = new StringBuilder();
      for (String email : emails) {
        b.append(email);
        annotations.get(email).forEach(annotation -> b.append(" #{" + annotation + "}"));
        b.append('\n');
      }
      return b.toString();
    }

    private static String formatPerFileCodeOwners(CodeOwnerConfig codeOwnerConfig) {
      StringBuilder b = new StringBuilder();
      codeOwnerConfig.codeOwnerSets().stream()
          // Filter out code owner sets without path expressions. If path expressions are absent the
          // code owner set defines global code owners and is handled in
          // formatGlobalCodeOwners(CodeOwnerConfig).
          .filter(codeOwnerSet -> !codeOwnerSet.pathExpressions().isEmpty())
          .map(Formatter::formatCodeOwnerSet)
          .forEach(b::append);
      return b.toString();
    }

    private static String formatCodeOwnerSet(CodeOwnerSet codeOwnerSet) {
      String formattedPathExpressions = formatValuesAsList(codeOwnerSet.pathExpressions());

      StringBuilder b = new StringBuilder();
      if (codeOwnerSet.ignoreGlobalAndParentCodeOwners()) {
        b.append(String.format(PER_FILE_LINE_FORMAT, formattedPathExpressions, TOK_SET_NOPARENT));
      }

      for (CodeOwnerConfigReference codeOwnerConfigReference : codeOwnerSet.imports()) {
        b.append(
            String.format(
                PER_FILE_LINE_FORMAT,
                formattedPathExpressions,
                formatImport(codeOwnerConfigReference)));
      }

      if (!codeOwnerSet.codeOwners().isEmpty()) {
        // group code owners that have the same annotations
        ListMultimap<SortedSet<String>, CodeOwnerReference> codeOwnersByAnnotations =
            MultimapBuilder.hashKeys().arrayListValues().build();
        codeOwnerSet
            .codeOwners()
            .forEach(
                codeOwnerReference ->
                    codeOwnersByAnnotations.put(
                        codeOwnerSet.annotations().get(codeOwnerReference).stream()
                            .map(CodeOwnerAnnotation::key)
                            .collect(toImmutableSortedSet(naturalOrder())),
                        codeOwnerReference));

        codeOwnersByAnnotations
            .asMap()
            .forEach(
                (annotations, codeOwners) ->
                    b.append(
                        String.format(
                            PER_FILE_LINE_FORMAT,
                            formattedPathExpressions,
                            formatCodeOwnerReferencesAsList(codeOwners)
                                + formatAnnotations(annotations))));
      }
      return b.toString();
    }

    private static String formatCodeOwnerReferencesAsList(
        Collection<CodeOwnerReference> codeOwnerReferences) {
      return formatValuesAsList(codeOwnerReferences.stream().map(CodeOwnerReference::email));
    }

    private static String formatAnnotations(SortedSet<String> annotations) {
      if (annotations.isEmpty()) {
        return "";
      }

      return annotations.stream()
          .map(annotation -> "#{" + annotation + "}")
          .collect(joining(" ", " ", ""));
    }

    private static String formatValuesAsList(ImmutableSet<String> values) {
      return formatValuesAsList(values.stream());
    }

    private static String formatValuesAsList(Stream<String> stream) {
      return stream.sorted().distinct().collect(joining(","));
    }

    private static String formatImports(CodeOwnerConfig codeOwnerConfig) {
      StringBuilder b = new StringBuilder();
      codeOwnerConfig
          .imports()
          .forEach(
              codeOwnerConfigReference ->
                  b.append(formatImport(codeOwnerConfigReference)).append('\n'));
      return b.toString();
    }

    private static String formatImport(CodeOwnerConfigReference codeOwnerConfigReference) {
      StringBuilder b = new StringBuilder();

      // write the keyword
      switch (codeOwnerConfigReference.importMode()) {
        case ALL:
          b.append("include ");
          break;
        case GLOBAL_CODE_OWNER_SETS_ONLY:
          b.append("file: ");
          break;
        default:
          throw new IllegalStateException(
              String.format("unknown import mode: %s", codeOwnerConfigReference.importMode()));
      }

      // write the project
      if (codeOwnerConfigReference.project().isPresent()) {
        b.append(codeOwnerConfigReference.project().get()).append(':');
      }

      // write the branch
      if (codeOwnerConfigReference.branch().isPresent()) {
        checkState(
            codeOwnerConfigReference.project().isPresent(),
            "project is required if branch is specified: %s",
            codeOwnerConfigReference);
        b.append(codeOwnerConfigReference.branch().get()).append(':');
      }

      // write the file path
      b.append(codeOwnerConfigReference.filePath());

      return b.toString();
    }
  }
}
