// Copyright (C) 2020 The Android Open Source Project
//
// 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.gerrit.entities;

import com.google.auto.value.AutoValue;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.ImmutableSortedMap;
import com.google.common.flogger.FluentLogger;
import com.google.errorprone.annotations.CanIgnoreReturnValue;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import org.eclipse.jgit.annotations.Nullable;
import org.eclipse.jgit.errors.ConfigInvalidException;
import org.eclipse.jgit.lib.ObjectId;

/**
 * Cached representation of values parsed from {@link
 * com.google.gerrit.server.project.ProjectConfig}.
 *
 * <p>This class is immutable and thread-safe.
 */
@AutoValue
public abstract class CachedProjectConfig {
  private static final FluentLogger logger = FluentLogger.forEnclosingClass();

  public abstract Project getProject();

  public abstract ImmutableMap<AccountGroup.UUID, GroupReference> getGroups();

  /** Returns a set of all groups used by this configuration. */
  public ImmutableSet<AccountGroup.UUID> getAllGroupUUIDs() {
    return getGroups().keySet();
  }

  /**
   * Returns the group reference for a {@link AccountGroup.UUID}, if the group is used by at least
   * one rule.
   */
  public Optional<GroupReference> getGroup(AccountGroup.UUID uuid) {
    return Optional.ofNullable(getGroups().get(uuid));
  }

  /**
   * Returns the group reference for matching the given {@code name}, if the group is used by at
   * least one rule.
   */
  public Optional<GroupReference> getGroupByName(@Nullable String name) {
    if (name == null) {
      return Optional.empty();
    }
    return getGroups().values().stream().filter(g -> name.equals(g.getName())).findAny();
  }

  /** Returns the account section containing visibility information about accounts. */
  public abstract AccountsSection getAccountsSection();

  /** Returns a map of {@link AccessSection}s keyed by their name. */
  public abstract ImmutableSortedMap<String, AccessSection> getAccessSections();

  /** Returns the {@link AccessSection} with to the given name. */
  public Optional<AccessSection> getAccessSection(String refName) {
    return Optional.ofNullable(getAccessSections().get(refName));
  }

  /** Returns all {@link AccessSection} names. */
  public ImmutableSet<String> getAccessSectionNames() {
    return ImmutableSet.copyOf(getAccessSections().keySet());
  }

  /**
   * Returns the {@link BranchOrderSection} containing the order in which branches should be shown.
   */
  public abstract Optional<BranchOrderSection> getBranchOrderSection();

  /** Returns the {@link ContributorAgreement}s keyed by their name. */
  public abstract ImmutableMap<String, ContributorAgreement> getContributorAgreements();

  /** Returns the {@link NotifyConfig}s keyed by their name. */
  public abstract ImmutableMap<String, NotifyConfig> getNotifySections();

  /** Returns the {@link LabelType}s keyed by their name. */
  public abstract ImmutableMap<String, LabelType> getLabelSections();

  /** Returns the {@link SubmitRequirement}s keyed by their name. */
  public abstract ImmutableMap<String, SubmitRequirement> getSubmitRequirementSections();

  /** Returns configured {@link ConfiguredMimeTypes}s. */
  public abstract ConfiguredMimeTypes getMimeTypes();

  /** Returns {@link SubscribeSection} keyed by the {@link Project.NameKey} they reference. */
  public abstract ImmutableMap<Project.NameKey, SubscribeSection> getSubscribeSections();

  /** Returns {@link StoredCommentLinkInfo} keyed by their name. */
  public abstract ImmutableMap<String, StoredCommentLinkInfo> getCommentLinkSections();

  /** Returns the blob ID of the {@code rules.pl} file, if present. */
  public abstract Optional<ObjectId> getRulesId();

  // TODO(hiesel): This should not have to be an Optional.
  /** Returns the SHA1 of the {@code refs/meta/config} branch. */
  public abstract Optional<ObjectId> getRevision();

  /** Returns the maximum allowed object size. */
  public abstract long getMaxObjectSizeLimit();

  /** Returns {@code true} if received objects should be checked for validity. */
  public abstract boolean getCheckReceivedObjects();

  /** Returns a list of panel sections keyed by title. */
  public abstract ImmutableMap<String, ImmutableList<String>> getExtensionPanelSections();

  public ImmutableList<SubscribeSection> getSubscribeSections(BranchNameKey branch) {
    return filterSubscribeSectionsByBranch(getSubscribeSections().values(), branch);
  }

  public abstract ImmutableMap<String, String> getPluginConfigs();

  public abstract ImmutableMap<String, String> getProjectLevelConfigs();

  public abstract ImmutableMap<String, ImmutableConfig> getParsedProjectLevelConfigs();

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

  public abstract Builder toBuilder();

  @AutoValue.Builder
  public abstract static class Builder {
    public abstract Builder setProject(Project value);

    public abstract Builder setAccountsSection(AccountsSection value);

    public abstract Builder setBranchOrderSection(Optional<BranchOrderSection> value);

    @CanIgnoreReturnValue
    public Builder addGroup(GroupReference groupReference) {
      groupsBuilder().put(groupReference.getUUID(), groupReference);
      return this;
    }

    @CanIgnoreReturnValue
    public Builder addAccessSection(AccessSection accessSection) {
      accessSectionsBuilder().put(accessSection.getName(), accessSection);
      return this;
    }

    @CanIgnoreReturnValue
    public Builder addContributorAgreement(ContributorAgreement contributorAgreement) {
      contributorAgreementsBuilder().put(contributorAgreement.getName(), contributorAgreement);
      return this;
    }

    @CanIgnoreReturnValue
    public Builder addNotifySection(NotifyConfig notifyConfig) {
      notifySectionsBuilder().put(notifyConfig.getName(), notifyConfig);
      return this;
    }

    @CanIgnoreReturnValue
    public Builder addLabelSection(LabelType labelType) {
      labelSectionsBuilder().put(labelType.getName(), labelType);
      return this;
    }

    @CanIgnoreReturnValue
    public Builder addSubmitRequirementSection(SubmitRequirement submitRequirement) {
      submitRequirementSectionsBuilder().put(submitRequirement.name(), submitRequirement);
      return this;
    }

    public abstract Builder setMimeTypes(ConfiguredMimeTypes value);

    @CanIgnoreReturnValue
    public Builder addSubscribeSection(SubscribeSection subscribeSection) {
      subscribeSectionsBuilder().put(subscribeSection.project(), subscribeSection);
      return this;
    }

    @CanIgnoreReturnValue
    public Builder addCommentLinkSection(StoredCommentLinkInfo storedCommentLinkInfo) {
      commentLinkSectionsBuilder().put(storedCommentLinkInfo.getName(), storedCommentLinkInfo);
      return this;
    }

    public abstract Builder setRulesId(Optional<ObjectId> value);

    public abstract Builder setRevision(Optional<ObjectId> value);

    public abstract Builder setMaxObjectSizeLimit(long value);

    public abstract Builder setCheckReceivedObjects(boolean value);

    public abstract ImmutableMap.Builder<String, ImmutableList<String>>
        extensionPanelSectionsBuilder();

    public Builder setExtensionPanelSections(Map<String, List<String>> value) {
      value
          .entrySet()
          .forEach(
              e ->
                  extensionPanelSectionsBuilder()
                      .put(e.getKey(), ImmutableList.copyOf(e.getValue())));
      return this;
    }

    abstract ImmutableMap.Builder<String, String> pluginConfigsBuilder();

    @CanIgnoreReturnValue
    public Builder addPluginConfig(String pluginName, String pluginConfig) {
      pluginConfigsBuilder().put(pluginName, pluginConfig);
      return this;
    }

    abstract ImmutableMap.Builder<String, String> projectLevelConfigsBuilder();

    abstract ImmutableMap.Builder<String, ImmutableConfig> parsedProjectLevelConfigsBuilder();

    @CanIgnoreReturnValue
    public Builder addProjectLevelConfig(String configFileName, String config) {
      projectLevelConfigsBuilder().put(configFileName, config);
      try {
        parsedProjectLevelConfigsBuilder().put(configFileName, ImmutableConfig.parse(config));
      } catch (ConfigInvalidException e) {
        logger.atInfo().withCause(e).log("Config for %s not parsable", configFileName);
      }
      return this;
    }

    public abstract CachedProjectConfig build();

    protected abstract ImmutableMap.Builder<AccountGroup.UUID, GroupReference> groupsBuilder();

    protected abstract ImmutableSortedMap.Builder<String, AccessSection> accessSectionsBuilder();

    protected abstract ImmutableMap.Builder<String, ContributorAgreement>
        contributorAgreementsBuilder();

    protected abstract ImmutableMap.Builder<String, NotifyConfig> notifySectionsBuilder();

    protected abstract ImmutableMap.Builder<String, LabelType> labelSectionsBuilder();

    protected abstract ImmutableMap.Builder<String, SubmitRequirement>
        submitRequirementSectionsBuilder();

    protected abstract ImmutableMap.Builder<Project.NameKey, SubscribeSection>
        subscribeSectionsBuilder();

    protected abstract ImmutableMap.Builder<String, StoredCommentLinkInfo>
        commentLinkSectionsBuilder();
  }

  private static ImmutableList<SubscribeSection> filterSubscribeSectionsByBranch(
      Collection<SubscribeSection> allSubscribeSections, BranchNameKey branch) {
    ImmutableList.Builder<SubscribeSection> ret = ImmutableList.builder();
    for (SubscribeSection s : allSubscribeSections) {
      if (s.appliesTo(branch)) {
        ret.add(s);
      }
    }
    return ret.build();
  }
}
