/*
 * Copyright 2016-present Facebook, 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.facebook.buck.cli;

import com.facebook.buck.core.cell.CellPathResolver;
import com.facebook.buck.util.ExitCode;
import com.facebook.buck.util.json.ObjectMappers;
import com.google.common.collect.ImmutableMap;
import java.io.IOException;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import org.kohsuke.args4j.Argument;
import org.kohsuke.args4j.Option;

public class AuditCellCommand extends AbstractCommand {

  @Option(name = "--json", usage = "Output in JSON format")
  private boolean generateJsonOutput;

  @Option(name = "--paths-only", usage = "Don't include the cell name in the output")
  private boolean pathsOnly;

  public boolean shouldGenerateJsonOutput() {
    return generateJsonOutput;
  }

  public boolean shouldIncludeCellNameInOutput() {
    return !pathsOnly;
  }

  @Argument private List<String> arguments = new ArrayList<>();

  public List<String> getArguments() {
    return arguments;
  }

  @Override
  public ExitCode runWithoutHelp(CommandRunnerParams params) throws Exception {
    ImmutableMap<String, Path> cellMap;
    if (getArguments().isEmpty()) {
      cellMap = params.getCell().getCellPathResolver().getCellPathsByRootCellExternalName();
    } else {
      CellPathResolver cellPathResolver = params.getCell().getCellPathResolver();
      ImmutableMap.Builder<String, Path> outputBuilder = ImmutableMap.builder();
      for (String arg : getArguments()) {
        Path cellPath = cellPathResolver.getCellPathOrThrow(Optional.of(arg));
        outputBuilder.put(arg, cellPath);
      }
      cellMap = outputBuilder.build();
    }

    if (shouldGenerateJsonOutput()) {
      printJsonOutput(params, cellMap);
    } else {
      printOutput(params, cellMap);
    }
    return ExitCode.SUCCESS;
  }

  private void printOutput(CommandRunnerParams params, ImmutableMap<String, Path> cellMap) {
    for (Map.Entry<String, Path> entry : cellMap.entrySet()) {
      String outputString =
          shouldIncludeCellNameInOutput()
              ? String.format("%s: %s", entry.getKey(), entry.getValue())
              : entry.getValue().toString();
      params.getConsole().getStdOut().println(outputString);
    }
  }

  private void printJsonOutput(CommandRunnerParams params, ImmutableMap<String, Path> cellMap)
      throws IOException {
    if (shouldIncludeCellNameInOutput()) {
      ObjectMappers.WRITER.writeValue(params.getConsole().getStdOut(), cellMap);
    } else {
      ObjectMappers.WRITER.writeValue(params.getConsole().getStdOut(), cellMap.values());
    }
  }

  @Override
  public boolean isReadOnly() {
    return true;
  }

  @Override
  public String getShortDescription() {
    return "Query information about the [repositories] list in .buckconfig.";
  }
}

@@ -671,28 +671,139 @@
 ell.Cell
-PathResolver
+NameResolver;%0Aimport com.facebook.buck.core.cell.NewCellPathResolver;%0Aimport com.facebook.buck.core.model.CanonicalCellName
 ;%0Aimport
@@ -1823,93 +1823,449 @@
     
-ImmutableMap%3CString, Path%3E cellMap;%0A    if (getArguments().isEmpty()) %7B%0A      cellMap
+// TODO(cjhopman): This command doesn't really seem to make sense. I think it needs to be%0A    // changed or better documented what it's doing if that's what's intended. I think it would make%0A    // more sense for it to print either a map of canonicalname -%3E path or to include the empty%0A    // alias in the map that it prints (then it's an alias -%3E path map).%0A    ImmutableMap%3CString, Path%3E cellMap;%0A    CellNameResolver rootCellNameResolver
  = p
@@ -2279,36 +2279,36 @@
 etCell().getCell
-Path
+Name
 Resolver().getCe
@@ -2305,57 +2305,126 @@
 er()
-.getCellPathsByRootCellExternalName
+;%0A    NewCellPathResolver pathResolver = params.getCell().getNewCellPathResolver
 ();%0A
+%0A
     
-%7D else
+if (getArguments().isEmpty())
  %7B%0A 
@@ -2432,283 +2432,577 @@
     
-CellPathResolver cellPathResolver = params.getCell().getCellPathResolver();%0A      ImmutableMap.Builder%3CString, Path%3E outputBuilder = ImmutableMap.builder();%0A      for (String arg : getArguments()) %7B%0A        Path cellPath = cellPathResolver.getCellPathOrThrow(Optional.of(arg)
+cellMap =%0A          rootCellNameResolver.getKnownCells().entrySet().stream()%0A              .filter(e -%3E e.getKey().isPresent())%0A              .collect(%0A                  ImmutableMap.toImmutableMap(%0A                      e -%3E e.getKey().get(), e -%3E pathResolver.getCellPath(e.getValue())));%0A    %7D else %7B%0A      ImmutableMap.Builder%3CString, Path%3E outputBuilder = ImmutableMap.builder();%0A      for (String arg : getArguments()) %7B%0A        CanonicalCellName cellName = rootCellNameResolver.getName(Optional.of(arg));%0A        Path cellPath = pathResolver.getCellPath(cellName
 );%0A 

Rewrite `buck audit cell` to be basd on new cell path/name resolution