// Copyright (C) 2017 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.server.group.db;

import com.google.common.base.Strings;
import com.google.gerrit.entities.AccountGroup;
import com.google.gerrit.entities.InternalGroup;
import org.eclipse.jgit.errors.ConfigInvalidException;
import org.eclipse.jgit.lib.Config;

/**
 * A basic property of a group.
 *
 * <p>Each property knows how to read and write its value from/to a JGit {@link Config} file.
 *
 * <p><strong>Warning:</strong> This class is a low-level API for properties of groups in NoteDb. It
 * may only be used by {@link GroupConfig}. Other classes should use {@link GroupDelta} to modify
 * the properties of a group.
 */
enum GroupConfigEntry {
  /**
   * The numeric ID of a group. This property is equivalent to {@link InternalGroup#getId()}.
   *
   * <p>This is a mandatory property which may not be changed.
   */
  ID("id") {
    @Override
    void readFromConfig(AccountGroup.UUID groupUuid, InternalGroup.Builder group, Config config)
        throws ConfigInvalidException {
      int id = config.getInt(SECTION_NAME, super.keyName, -1);
      if (id < 0) {
        throw new ConfigInvalidException(
            String.format(
                "ID of the group %s must not be negative, found %d", groupUuid.get(), id));
      }
      group.setId(AccountGroup.id(id));
    }

    @Override
    void initNewConfig(Config config, InternalGroupCreation group) {
      AccountGroup.Id id = group.getId();

      // Do not use config.setInt(...) to write the group ID because config.setInt(...) persists
      // integers that can be expressed in KiB as a unit strings, e.g. "1024" is stored as "1k".
      // Using config.setString(...) ensures that group IDs are human readable.
      config.setString(SECTION_NAME, null, super.keyName, Integer.toString(id.get()));
    }

    @Override
    void updateConfigValue(Config config, GroupDelta groupDelta) {
      // Updating the ID is not supported.
    }
  },
  /**
   * The name of a group. This property is equivalent to {@link InternalGroup#getNameKey()}.
   *
   * <p>This is a mandatory property.
   */
  NAME("name") {
    @Override
    void readFromConfig(AccountGroup.UUID groupUuid, InternalGroup.Builder group, Config config) {
      String name = config.getString(SECTION_NAME, null, super.keyName);
      // An empty name is invalid in NoteDb; GroupConfig will refuse to store it and it might be
      // unusable in permissions. But, it was technically valid in the ReviewDb storage layer, and
      // the NoteDb migration converted such groups faithfully, so we need to be able to read them
      // back here.
      name = Strings.nullToEmpty(name);
      group.setNameKey(AccountGroup.nameKey(name));
    }

    @Override
    void initNewConfig(Config config, InternalGroupCreation group) {
      AccountGroup.NameKey name = group.getNameKey();
      config.setString(SECTION_NAME, null, super.keyName, name.get());
    }

    @Override
    void updateConfigValue(Config config, GroupDelta groupDelta) {
      groupDelta
          .getName()
          .ifPresent(name -> config.setString(SECTION_NAME, null, super.keyName, name.get()));
    }
  },
  /**
   * The description of a group. This property is equivalent to {@link
   * InternalGroup#getDescription()}.
   *
   * <p>It defaults to {@code null} if not set.
   */
  DESCRIPTION("description") {
    @Override
    void readFromConfig(AccountGroup.UUID groupUuid, InternalGroup.Builder group, Config config) {
      String description = config.getString(SECTION_NAME, null, super.keyName);
      group.setDescription(Strings.emptyToNull(description));
    }

    @Override
    void initNewConfig(Config config, InternalGroupCreation group) {
      config.setString(SECTION_NAME, null, super.keyName, null);
    }

    @Override
    void updateConfigValue(Config config, GroupDelta groupDelta) {
      groupDelta
          .getDescription()
          .ifPresent(
              description ->
                  config.setString(
                      SECTION_NAME, null, super.keyName, Strings.emptyToNull(description)));
    }
  },
  /**
   * The owner of a group. This property is equivalent to {@link InternalGroup#getOwnerGroupUUID()}.
   *
   * <p>It defaults to the group itself if not set.
   */
  OWNER_GROUP_UUID("ownerGroupUuid") {
    @Override
    void readFromConfig(AccountGroup.UUID groupUuid, InternalGroup.Builder group, Config config)
        throws ConfigInvalidException {
      String ownerGroupUuid = config.getString(SECTION_NAME, null, super.keyName);
      if (Strings.isNullOrEmpty(ownerGroupUuid)) {
        throw new ConfigInvalidException(
            String.format("Owner UUID of the group %s must be defined", groupUuid.get()));
      }
      group.setOwnerGroupUUID(AccountGroup.uuid(ownerGroupUuid));
    }

    @Override
    void initNewConfig(Config config, InternalGroupCreation group) {
      config.setString(SECTION_NAME, null, super.keyName, group.getGroupUUID().get());
    }

    @Override
    void updateConfigValue(Config config, GroupDelta groupDelta) {
      groupDelta
          .getOwnerGroupUUID()
          .ifPresent(
              ownerGroupUuid ->
                  config.setString(SECTION_NAME, null, super.keyName, ownerGroupUuid.get()));
    }
  },
  /**
   * A flag indicating the visibility of a group. This property is equivalent to {@link
   * InternalGroup#isVisibleToAll()}.
   *
   * <p>It defaults to {@code false} if not set.
   */
  VISIBLE_TO_ALL("visibleToAll") {
    @Override
    void readFromConfig(AccountGroup.UUID groupUuid, InternalGroup.Builder group, Config config) {
      boolean visibleToAll = config.getBoolean(SECTION_NAME, super.keyName, false);
      group.setVisibleToAll(visibleToAll);
    }

    @Override
    void initNewConfig(Config config, InternalGroupCreation group) {
      config.setBoolean(SECTION_NAME, null, super.keyName, false);
    }

    @Override
    void updateConfigValue(Config config, GroupDelta groupDelta) {
      groupDelta
          .getVisibleToAll()
          .ifPresent(
              visibleToAll -> config.setBoolean(SECTION_NAME, null, super.keyName, visibleToAll));
    }
  };

  private static final String SECTION_NAME = "group";

  private final String keyName;

  GroupConfigEntry(String keyName) {
    this.keyName = keyName;
  }

  /**
   * Reads the corresponding property of this {@code GroupConfigEntry} from the given {@code
   * Config}. The read value is written to the corresponding property of {@code
   * InternalGroup.Builder}.
   *
   * @param groupUuid the UUID of the group (necessary for helpful error messages)
   * @param group the {@code InternalGroup.Builder} whose property value should be set
   * @param config the {@code Config} from which the value of the property should be read
   * @throws ConfigInvalidException if the property has an unexpected value
   */
  abstract void readFromConfig(
      AccountGroup.UUID groupUuid, InternalGroup.Builder group, Config config)
      throws ConfigInvalidException;

  /**
   * Initializes the corresponding property of this {@code GroupConfigEntry} in the given {@code
   * Config}.
   *
   * <p>If the specified {@code InternalGroupCreation} has an entry for the property, that value is
   * used. If not, the default value for the property is set. In any case, an existing entry for the
   * property in the {@code Config} will be overwritten.
   *
   * @param config a new {@code Config}, typically without an entry for the property
   * @param group an {@code InternalGroupCreation} detailing the initial value of mandatory group
   *     properties
   */
  abstract void initNewConfig(Config config, InternalGroupCreation group);

  /**
   * Updates the corresponding property of this {@code GroupConfigEntry} in the given {@code Config}
   * if the {@link GroupDelta} mentions a modification.
   *
   * <p>This call is a no-op if the {@link GroupDelta} doesn't contain a modification for the
   * property.
   *
   * @param config a {@code Config} for which the property should be updated
   * @param groupDelta a {@link GroupDelta} detailing the modifications on a group
   */
  abstract void updateConfigValue(Config config, GroupDelta groupDelta);
}
