// Copyright 2020 The Bazel Authors. All rights reserved.
//
// 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.devtools.build.lib.rules.objc;

import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.base.Preconditions.checkState;

import com.google.devtools.build.lib.testutil.Scratch;
import com.google.errorprone.annotations.CanIgnoreReturnValue;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import javax.annotation.Nullable;

class BuildFileBuilder {

  private static class Version {
    String name;
    String version;
    String[] aliases;

    Version(String name, String version, String... aliases) {
      this.name = name;
      this.version = version;
      this.aliases = aliases;
    }
  }

  private final HashMap<String, Version> allVersions = new HashMap<>();
  private final List<Version> localVersions = new ArrayList<>();
  private final List<Version> remoteVersions = new ArrayList<>();
  private final List<Version> explicitVersions = new ArrayList<>();

  @Nullable private String localDefaultLabel;
  @Nullable private String remoteDefaultLabel;
  @Nullable private String explicitDefaultLabel;

  /**
   * Registers a new local version.
   *
   * <p>Only one local version may set {@code isDefault} to true.
   *
   * @param name the name of the version
   * @param versionNumber the version number
   * @param isDefault whether this version is the local default
   * @param aliases the aliases for this version
   */
  @CanIgnoreReturnValue
  BuildFileBuilder addLocalVersion(
      String name, String versionNumber, boolean isDefault, String... aliases) {
    Version version = new Version(name, versionNumber, aliases);
    allVersions.put(name, version);
    localVersions.add(version);
    if (isDefault) {
      checkState(localDefaultLabel == null, "Only one local version may set 'isDefault=true'");
      localDefaultLabel = name;
    }
    return this;
  }

  /**
   * Registers a new remote version.
   *
   * <p>Only one remote version may set {@code isDefault} to true.
   *
   * @param name the name of the version
   * @param versionNumber the version number
   * @param isDefault whether this version is the remote default
   * @param aliases the aliases for this version
   */
  @CanIgnoreReturnValue
  BuildFileBuilder addRemoteVersion(
      String name, String versionNumber, boolean isDefault, String... aliases) {
    Version version = new Version(name, versionNumber, aliases);
    allVersions.put(name, version);
    remoteVersions.add(version);
    if (isDefault) {
      checkState(remoteDefaultLabel == null, "Only one remote version may set 'isDefault=true'");
      remoteDefaultLabel = name;
    }
    return this;
  }

  /**
   * Registers a new explicit version.
   *
   * <p>Only one explicit version may set {@code isDefault} to true.
   *
   * @param name the name of the version
   * @param versionNumber the version number
   * @param isDefault whether this version is the default
   * @param aliases the aliases for this version
   */
  @CanIgnoreReturnValue
  BuildFileBuilder addExplicitVersion(
      String name, String versionNumber, boolean isDefault, String... aliases) {
    Version version = new Version(name, versionNumber, aliases);
    allVersions.put(name, version);
    explicitVersions.add(version);
    if (isDefault) {
      checkState(
          explicitDefaultLabel == null, "Only one explicit version may set 'isDefault=true'");
      explicitDefaultLabel = name;
    }
    return this;
  }

  private static void writeVersion(Version version, List<String> lines) {
    lines.add("xcode_version(");
    lines.add(String.format("    name = '%s',", version.name));
    lines.add(String.format("    version = '%s',", version.version));
    if (version.aliases.length != 0) {
      lines.add(String.format("    aliases = ['%s'],", String.join("', '", version.aliases)));
    }
    lines.add(")");
  }

  private static String formatVersionNames(List<Version> versions) {
    String versionNames = "";
    for (Version version : versions) {
      versionNames += String.format("':%s', ", version.name);
    }
    return "[" + versionNames + "]";
  }

  private static void writeAvailableXcodes(
      String name, String defaultVersion, List<Version> versions, List<String> lines) {
    lines.add("available_xcodes(");
    lines.add(String.format("    name = '%s',", name));
    lines.add(String.format("    default = ':%s',", defaultVersion));
    lines.add(String.format("    versions = %s,", formatVersionNames(versions)));
    lines.add(")");
  }

  private void writeAllAvailableXcodes(List<String> lines) {
    if (!localVersions.isEmpty()) {
      checkNotNull(localDefaultLabel, "One local version must be labeled as the default");
      writeAvailableXcodes("local", localDefaultLabel, localVersions, lines);
    }
    if (!remoteVersions.isEmpty()) {
      checkNotNull(remoteDefaultLabel, "One remote version must be labeled as the default");
      writeAvailableXcodes("remote", remoteDefaultLabel, remoteVersions, lines);
    }
  }

  private static void writeLocalRemoteXcodeConfig(List<String> lines) {
    lines.add("xcode_config(");
    lines.add("    name = 'foo',");
    lines.add("    local_versions = 'local',");
    lines.add("    remote_versions = 'remote',");
    lines.add(")");
  }

  private void writeStandardXcodeConfig(List<String> lines) {
    if (!explicitVersions.isEmpty()) {
      checkNotNull(
          explicitDefaultLabel, "'default' is a required field for the 'xcode_config' rule");
      lines.add("xcode_config(");
      lines.add("    name = 'foo',");
      lines.add(String.format("    default = '%s',", explicitDefaultLabel));
      lines.add(String.format("    versions = %s,", formatVersionNames(explicitVersions)));
      lines.add(")");
    }
  }

  void write(Scratch scratch, String filename) throws IOException {
    List<String> lines = new ArrayList<>();
    for (Version version : allVersions.values()) {
      writeVersion(version, lines);
    }

    if (!localVersions.isEmpty() && !remoteVersions.isEmpty()) {
      writeAllAvailableXcodes(lines);
      writeLocalRemoteXcodeConfig(lines);
    }
    if (!explicitVersions.isEmpty()) {
      writeStandardXcodeConfig(lines);
    }
    scratch.file(filename, lines.toArray(new String[0]));
  }
}
