// 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.server.cache.serialize.entities;

import static com.google.common.collect.ImmutableList.toImmutableList;

import com.google.common.base.Converter;
import com.google.common.base.Enums;
import com.google.common.collect.ImmutableList;
import com.google.common.primitives.Shorts;
import com.google.gerrit.entities.LabelFunction;
import com.google.gerrit.entities.LabelType;
import com.google.gerrit.server.cache.proto.Cache;

/** Helper to (de)serialize values for caches. */
public class LabelTypeSerializer {
  private static final Converter<String, LabelFunction> FUNCTION_CONVERTER =
      Enums.stringConverter(LabelFunction.class);

  public static LabelType deserialize(Cache.LabelTypeProto proto) {
    return LabelType.builder(
            proto.getName(),
            proto.getValuesList().stream()
                .map(LabelValueSerializer::deserialize)
                .collect(toImmutableList()))
        .setFunction(FUNCTION_CONVERTER.convert(proto.getFunction()))
        .setAllowPostSubmit(proto.getAllowPostSubmit())
        .setIgnoreSelfApproval(proto.getIgnoreSelfApproval())
        .setDefaultValue(Shorts.saturatedCast(proto.getDefaultValue()))
        .setCopyAnyScore(proto.getCopyAnyScore())
        .setCopyMinScore(proto.getCopyMinScore())
        .setCopyMaxScore(proto.getCopyMaxScore())
        .setCopyAllScoresIfListOfFilesDidNotChange(
            proto.getCopyAllScoresIfListOfFilesDidNotChange())
        .setCopyAllScoresOnMergeFirstParentUpdate(proto.getCopyAllScoresOnMergeFirstParentUpdate())
        .setCopyAllScoresOnTrivialRebase(proto.getCopyAllScoresOnTrivialRebase())
        .setCopyAllScoresIfNoCodeChange(proto.getCopyAllScoresIfNoCodeChange())
        .setCopyAllScoresIfNoChange(proto.getCopyAllScoresIfNoChange())
        .setCopyValues(
            proto.getCopyValuesList().stream()
                .map(Shorts::saturatedCast)
                .collect(toImmutableList()))
        .setMaxNegative(Shorts.saturatedCast(proto.getMaxNegative()))
        .setMaxPositive(Shorts.saturatedCast(proto.getMaxPositive()))
        .setRefPatterns(proto.getRefPatternsList())
        .setCanOverride(proto.getCanOverride())
        .build();
  }

  public static Cache.LabelTypeProto serialize(LabelType autoValue) {
    return Cache.LabelTypeProto.newBuilder()
        .setName(autoValue.getName())
        .addAllValues(
            autoValue.getValues().stream()
                .map(LabelValueSerializer::serialize)
                .collect(toImmutableList()))
        .setFunction(FUNCTION_CONVERTER.reverse().convert(autoValue.getFunction()))
        .setCopyAnyScore(autoValue.isCopyAnyScore())
        .setCopyMinScore(autoValue.isCopyMinScore())
        .setCopyMaxScore(autoValue.isCopyMaxScore())
        .setCopyAllScoresIfListOfFilesDidNotChange(
            autoValue.isCopyAllScoresIfListOfFilesDidNotChange())
        .setCopyAllScoresOnMergeFirstParentUpdate(
            autoValue.isCopyAllScoresOnMergeFirstParentUpdate())
        .setCopyAllScoresOnTrivialRebase(autoValue.isCopyAllScoresOnTrivialRebase())
        .setCopyAllScoresIfNoCodeChange(autoValue.isCopyAllScoresIfNoCodeChange())
        .setCopyAllScoresIfNoChange(autoValue.isCopyAllScoresIfNoChange())
        .addAllCopyValues(
            autoValue.getCopyValues().stream().map(c -> (int) c).collect(toImmutableList()))
        .setAllowPostSubmit(autoValue.isAllowPostSubmit())
        .setIgnoreSelfApproval(autoValue.isIgnoreSelfApproval())
        .setDefaultValue(Shorts.saturatedCast(autoValue.getDefaultValue()))
        .setMaxNegative(Shorts.saturatedCast(autoValue.getMaxNegative()))
        .setMaxPositive(Shorts.saturatedCast(autoValue.getMaxPositive()))
        .addAllRefPatterns(
            autoValue.getRefPatterns() == null ? ImmutableList.of() : autoValue.getRefPatterns())
        .setCanOverride(autoValue.isCanOverride())
        .build();
  }

  private LabelTypeSerializer() {}
}
