/*
 * 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 JavaRuleIdeInfo}
 */
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();
  }

  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
    );
  }
}
