/*
 * 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.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
import com.google.copybara.Info.MigrationReference;
import com.google.copybara.config.ConfigFile;
import com.google.copybara.config.SkylarkParser;
import com.google.copybara.folder.FolderDestinationOptions;
import com.google.copybara.folder.FolderModule;
import com.google.copybara.folder.FolderOriginOptions;
import com.google.copybara.git.GerritOptions;
import com.google.copybara.git.GitDestinationOptions;
import com.google.copybara.git.GitMirrorOptions;
import com.google.copybara.git.GitModule;
import com.google.copybara.git.GitOptions;
import com.google.copybara.modules.PatchModule;
import com.google.copybara.transform.metadata.MetadataModule;
import com.google.copybara.util.console.Console;
import java.io.IOException;
import java.nio.file.Path;
import java.util.List;
import javax.annotation.Nullable;

/**
 * Copybara tool main class.
 *
 * <p>Executes Copybara workflows independently from the environment that they are invoked from
 * (command-line, service).
 */
public class Copybara {

  private final SkylarkParser skylarkParser;

  public Copybara(SkylarkParser skylarkParser) {
    this.skylarkParser = Preconditions.checkNotNull(skylarkParser);
  }

  public void run(Options options, ConfigFile configContents, String migrationName,
      Path baseWorkdir, @Nullable String sourceRef)
      throws RepoException, ValidationException, IOException {
    Config config = loadConfig(options, configContents);
    config.getMigration(migrationName).run(baseWorkdir, sourceRef);
  }

  public void info(Options options, ConfigFile configContents, String migrationName)
      throws IOException, ValidationException, RepoException {
    Console console = options.get(GeneralOptions.class).console();
    Config config = loadConfig(options, configContents);
    Info info = config.getMigration(migrationName).getInfo();
    for (MigrationReference ref : info.migrationReferences()) {
      console.info(
          String.format("'%s': last_migrated %s - last_available %s.",
              ref.getLabel(),
              ref.getLastMigrated() != null ? ref.getLastMigrated().asString() : "None",
              ref.getNextToMigrate() != null ? ref.getNextToMigrate().asString() : "None"));
    }
  }

  public void validate(Options options, ConfigFile configContent)
      throws RepoException, ValidationException, IOException {
    Console console = options.get(GeneralOptions.class).console();
    Config config = skylarkParser.loadConfig(configContent, options);
    validateConfig(options, config);
    console.info("Configuration validated.");
  }

  private Config loadConfig(Options options, ConfigFile configContents)
      throws IOException, ValidationException {
    GeneralOptions generalOptions = options.get(GeneralOptions.class);
    Config config = skylarkParser.loadConfig(configContents, options);
    Console console = generalOptions.console();
    console.progress("Validating configuration");
    validateConfig(options, config);
    return config;
  }

  private void validateConfig(Options options, Config config) throws ValidationException {
    Console console = options.get(GeneralOptions.class).console();
    List<String> validationMessages = validateConfig(config);
    if (!validationMessages.isEmpty()) {
      console.error("Configuration is invalid:");
      for (String validationMessage : validationMessages) {
        console.error(validationMessage);
      }
      throw new ValidationException("Error validating configuration: Configuration is invalid.");
    }
  }

  /**
   * Returns a list of validation error messages, if any, for the given configuration.
   */
  protected List<String> validateConfig(Config config) {
    // TODO(copybara-team): Move here SkylarkParser validations once Config has all the workflows.
    // checkCondition(!workflows.isEmpty(), ...)
    return ImmutableList.of();
  }
}

@@ -716,55 +716,8 @@
 st;%0A
-import com.google.common.collect.ImmutableSet;%0A
 impo
@@ -863,515 +863,8 @@
 er;%0A
-import com.google.copybara.folder.FolderDestinationOptions;%0Aimport com.google.copybara.folder.FolderModule;%0Aimport com.google.copybara.folder.FolderOriginOptions;%0Aimport com.google.copybara.git.GerritOptions;%0Aimport com.google.copybara.git.GitDestinationOptions;%0Aimport com.google.copybara.git.GitMirrorOptions;%0Aimport com.google.copybara.git.GitModule;%0Aimport com.google.copybara.git.GitOptions;%0Aimport com.google.copybara.modules.PatchModule;%0Aimport com.google.copybara.transform.metadata.MetadataModule;%0A
 impo

Remove unused imports.