// Copyright (C) 2022 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.query.change;

import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.gerrit.entities.Change;
import com.google.gerrit.server.config.GerritImportedServerIds;
import com.google.gerrit.server.config.GerritServerId;
import com.google.inject.Inject;
import com.google.inject.ProvisionException;
import com.google.inject.Singleton;

/**
 * Dictionary-based encoding algorithm for combining a serverId/legacyChangeNum into a virtual
 * numeric id
 *
 * <p>TODO: To be reverted on master and stable-3.8
 */
@Singleton
public class ChangeNumberBitmapMaskAlgorithm implements ChangeNumberVirtualIdAlgorithm {
  /*
   * Bit-wise masks for representing the Change's VirtualId as combination of ServerId + ChangeNum:
   */
  private static final int CHANGE_NUM_BIT_LEN = 28; // Allows up to 268M changes
  private static final int LEGACY_ID_BIT_MASK = (1 << CHANGE_NUM_BIT_LEN) - 1;
  private static final int SERVER_ID_BIT_LEN =
      Integer.BYTES * 8 - CHANGE_NUM_BIT_LEN; // Allows up to 64 ServerIds

  private final ImmutableMap<String, Integer> serverIdCodes;
  private final String localServerId;

  @Inject
  public ChangeNumberBitmapMaskAlgorithm(
      @GerritServerId String localServerId,
      @GerritImportedServerIds ImmutableList<String> importedServerIds) {
    if (importedServerIds.size() >= 1 << SERVER_ID_BIT_LEN) {
      throw new ProvisionException(
          String.format(
              "Too many imported GerritServerIds (%d) to fit into the Change virtual id",
              importedServerIds.size()));
    }
    ImmutableMap.Builder<String, Integer> serverIdCodesBuilder = new ImmutableMap.Builder<>();
    for (int i = 0; i < importedServerIds.size(); i++) {
      serverIdCodesBuilder.put(importedServerIds.get(i), i + 1);
    }

    serverIdCodes = serverIdCodesBuilder.build();
    this.localServerId = localServerId;
  }

  @Override
  public Change.Id apply(String changeServerId, Change.Id changeNumId) {
    if (changeServerId == null || localServerId.equals(changeServerId)) {
      return changeNumId;
    }

    int changeNum = changeNumId.get();

    if ((changeNum & LEGACY_ID_BIT_MASK) != changeNum) {
      throw new IllegalArgumentException(
          String.format(
              "Change number %d is too large to be converted into a virtual id", changeNum));
    }

    Integer encodedServerId = serverIdCodes.get(changeServerId);
    if (encodedServerId == null) {
      throw new IllegalArgumentException(
          String.format("ServerId %s is not part of the GerritImportedServerIds", changeServerId));
    }
    int virtualId = (changeNum & LEGACY_ID_BIT_MASK) | (encodedServerId << CHANGE_NUM_BIT_LEN);

    return Change.id(virtualId);
  }
}
