/*
 * Copyright 2016 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.idea.blaze.base.ideinfo;

import com.google.common.base.Objects;
import com.google.common.collect.ImmutableList;
import com.google.idea.blaze.base.model.primitives.ExecutionRootPath;
import java.io.Serializable;

/** Sister class to {@link JavaIdeInfo} */
public class CToolchainIdeInfo implements Serializable {
  private static final long serialVersionUID = 3L;

  public final ImmutableList<String> baseCompilerOptions;
  public final ImmutableList<String> cCompilerOptions;
  public final ImmutableList<String> cppCompilerOptions;
  public final ImmutableList<String> linkOptions;
  public final ImmutableList<ExecutionRootPath> builtInIncludeDirectories;
  public final ExecutionRootPath cppExecutable;
  public final ExecutionRootPath preprocessorExecutable;
  public final String targetName;

  public final ImmutableList<String> unfilteredCompilerOptions;
  public final ImmutableList<ExecutionRootPath> unfilteredToolchainSystemIncludes;

  public CToolchainIdeInfo(
      ImmutableList<String> baseCompilerOptions,
      ImmutableList<String> cCompilerOptions,
      ImmutableList<String> cppCompilerOptions,
      ImmutableList<String> linkOptions,
      ImmutableList<ExecutionRootPath> builtInIncludeDirectories,
      ExecutionRootPath cppExecutable,
      ExecutionRootPath preprocessorExecutable,
      String targetName,
      ImmutableList<String> unfilteredCompilerOptions,
      ImmutableList<ExecutionRootPath> unfilteredToolchainSystemIncludes) {
    this.baseCompilerOptions = baseCompilerOptions;
    this.cCompilerOptions = cCompilerOptions;
    this.cppCompilerOptions = cppCompilerOptions;
    this.linkOptions = linkOptions;
    this.builtInIncludeDirectories = builtInIncludeDirectories;
    this.cppExecutable = cppExecutable;
    this.preprocessorExecutable = preprocessorExecutable;
    this.targetName = targetName;
    this.unfilteredCompilerOptions = unfilteredCompilerOptions;
    this.unfilteredToolchainSystemIncludes = unfilteredToolchainSystemIncludes;
  }

  public static Builder builder() {
    return new Builder();
  }

  /** Builder for c toolchain */
  public static class Builder {
    private final ImmutableList.Builder<String> baseCompilerOptions = ImmutableList.builder();
    private final ImmutableList.Builder<String> cCompilerOptions = ImmutableList.builder();
    private final ImmutableList.Builder<String> cppCompilerOptions = ImmutableList.builder();
    private final ImmutableList.Builder<String> linkOptions = ImmutableList.builder();

    private final ImmutableList.Builder<ExecutionRootPath> builtInIncludeDirectories =
        ImmutableList.builder();

    ExecutionRootPath cppExecutable;
    ExecutionRootPath preprocessorExecutable;

    String targetName = "";

    private final ImmutableList.Builder<String> unfilteredCompilerOptions = ImmutableList.builder();
    private final ImmutableList.Builder<ExecutionRootPath> unfilteredToolchainSystemIncludes =
        ImmutableList.builder();

    public Builder addBaseCompilerOptions(Iterable<String> baseCompilerOptions) {
      this.baseCompilerOptions.addAll(baseCompilerOptions);
      return this;
    }

    public Builder addCCompilerOptions(Iterable<String> cCompilerOptions) {
      this.cCompilerOptions.addAll(cCompilerOptions);
      return this;
    }

    public Builder addCppCompilerOptions(Iterable<String> cppCompilerOptions) {
      this.cppCompilerOptions.addAll(cppCompilerOptions);
      return this;
    }

    public Builder addLinkOptions(Iterable<String> linkOptions) {
      this.linkOptions.addAll(linkOptions);
      return this;
    }

    public Builder addBuiltInIncludeDirectories(
        Iterable<ExecutionRootPath> builtInIncludeDirectories) {
      this.builtInIncludeDirectories.addAll(builtInIncludeDirectories);
      return this;
    }

    public Builder setCppExecutable(ExecutionRootPath cppExecutable) {
      this.cppExecutable = cppExecutable;
      return this;
    }

    public Builder setPreprocessorExecutable(ExecutionRootPath preprocessorExecutable) {
      this.preprocessorExecutable = preprocessorExecutable;
      return this;
    }

    public Builder setTargetName(String targetName) {
      this.targetName = targetName;
      return this;
    }

    public Builder addUnfilteredCompilerOptions(Iterable<String> unfilteredCompilerOptions) {
      this.unfilteredCompilerOptions.addAll(unfilteredCompilerOptions);
      return this;
    }

    public Builder addUnfilteredToolchainSystemIncludes(
        Iterable<ExecutionRootPath> unfilteredToolchainSystemIncludes) {
      this.unfilteredToolchainSystemIncludes.addAll(unfilteredToolchainSystemIncludes);
      return this;
    }

    public CToolchainIdeInfo build() {
      return new CToolchainIdeInfo(
          baseCompilerOptions.build(),
          cCompilerOptions.build(),
          cppCompilerOptions.build(),
          linkOptions.build(),
          builtInIncludeDirectories.build(),
          cppExecutable,
          preprocessorExecutable,
          targetName,
          unfilteredCompilerOptions.build(),
          unfilteredToolchainSystemIncludes.build());
    }
  }

  @Override
  public String toString() {
    return "CToolchainIdeInfo{"
        + "\n"
        + "  baseCompilerOptions="
        + baseCompilerOptions
        + "\n"
        + "  cCompilerOptions="
        + cCompilerOptions
        + "\n"
        + "  cppCompilerOptions="
        + cppCompilerOptions
        + "\n"
        + "  linkOptions="
        + linkOptions
        + "\n"
        + "  builtInIncludeDirectories="
        + builtInIncludeDirectories
        + "\n"
        + "  cppExecutable='"
        + cppExecutable
        + '\''
        + "\n"
        + "  preprocessorExecutable='"
        + preprocessorExecutable
        + '\''
        + "\n"
        + "  targetName='"
        + targetName
        + '\''
        + "\n"
        + "  unfilteredCompilerOptions="
        + unfilteredCompilerOptions
        + "\n"
        + "  unfilteredToolchainSystemIncludes="
        + unfilteredToolchainSystemIncludes
        + "\n"
        + '}';
  }

  @Override
  public boolean equals(Object o) {
    if (this == o) {
      return true;
    }
    if (o == null || getClass() != o.getClass()) {
      return false;
    }
    CToolchainIdeInfo that = (CToolchainIdeInfo) o;
    return Objects.equal(baseCompilerOptions, that.baseCompilerOptions)
        && Objects.equal(cCompilerOptions, that.cCompilerOptions)
        && Objects.equal(cppCompilerOptions, that.cppCompilerOptions)
        && Objects.equal(linkOptions, that.linkOptions)
        && Objects.equal(builtInIncludeDirectories, that.builtInIncludeDirectories)
        && Objects.equal(cppExecutable, that.cppExecutable)
        && Objects.equal(preprocessorExecutable, that.preprocessorExecutable)
        && Objects.equal(targetName, that.targetName)
        && Objects.equal(unfilteredCompilerOptions, that.unfilteredCompilerOptions)
        && Objects.equal(unfilteredToolchainSystemIncludes, that.unfilteredToolchainSystemIncludes);
  }

  @Override
  public int hashCode() {
    return Objects.hashCode(
        baseCompilerOptions,
        cCompilerOptions,
        cppCompilerOptions,
        linkOptions,
        builtInIncludeDirectories,
        cppExecutable,
        preprocessorExecutable,
        targetName,
        unfilteredCompilerOptions,
        unfilteredToolchainSystemIncludes);
  }
}
