// 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.gerrit.server.logging.Metadata;
import com.google.gerrit.server.logging.TraceContext;
import com.google.gerrit.server.logging.TraceContext.TraceTimer;
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();
    try (TraceTimer timer =
        TraceContext.newTimer(
            "ChangeNumberBitmapMaskAlgorithm", Metadata.builder().changeId(changeNum).build())) {
      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);
    }
  }
}
