// Copyright (c) 2019, the R8 project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

package com.android.tools.r8.ir.analysis.proto.schema;

import static com.android.tools.r8.ir.analysis.proto.schema.ProtoOneOfFieldType.FIRST_ONE_OF_ID;
import static com.android.tools.r8.utils.BitUtils.isBitSet;

import com.android.tools.r8.utils.BooleanUtils;

public class ProtoFieldType {

  public static final int MESSAGE_ID = 9;
  public static final int ENUM_ID = 12;
  public static final int GROUP_ID = 17;
  public static final int MESSAGE_LIST_ID = 27;
  public static final int ENUM_LIST_ID = 30;
  public static final int ENUM_LIST_PACKAGED_ID = 44;
  public static final int GROUP_LIST_ID = 49;
  public static final int MAP_ID = 50;

  private static final int FIELD_ID_MASK = 0xFF;
  private static final int FIELD_IS_REQUIRED_MASK = 0x100;
  private static final int FIELD_NEEDS_IS_INITIALIZED_CHECK_MASK = 0x400;
  private static final int FIELD_IS_MAP_FIELD_WITH_PROTO_2_ENUM_VALUE_MASK = 0x800;

  private final int id;
  private final boolean isRequired;
  private final boolean needsIsInitializedCheck;
  private final boolean isMapFieldWithProto2EnumValue;

  ProtoFieldType(
      int id,
      boolean isRequired,
      boolean needsIsInitializedCheck,
      boolean isMapFieldWithProto2EnumValue) {
    this.id = id;
    this.isRequired = isRequired;
    this.needsIsInitializedCheck = needsIsInitializedCheck;
    this.isMapFieldWithProto2EnumValue = isMapFieldWithProto2EnumValue;
    assert isValid();
  }

  static ProtoFieldType fromFieldIdWithExtraBits(int fieldTypeWithExtraBits) {
    int fieldId = fieldTypeWithExtraBits & FIELD_ID_MASK;
    if (fieldId < FIRST_ONE_OF_ID) {
      return new ProtoFieldType(
          fieldTypeWithExtraBits & FIELD_ID_MASK,
          isBitSet(fieldTypeWithExtraBits, FIELD_IS_REQUIRED_MASK),
          isBitSet(fieldTypeWithExtraBits, FIELD_NEEDS_IS_INITIALIZED_CHECK_MASK),
          isBitSet(fieldTypeWithExtraBits, FIELD_IS_MAP_FIELD_WITH_PROTO_2_ENUM_VALUE_MASK));
    } else {
      return new ProtoOneOfFieldType(
          fieldTypeWithExtraBits & FIELD_ID_MASK,
          isBitSet(fieldTypeWithExtraBits, FIELD_IS_REQUIRED_MASK),
          isBitSet(fieldTypeWithExtraBits, FIELD_NEEDS_IS_INITIALIZED_CHECK_MASK),
          isBitSet(fieldTypeWithExtraBits, FIELD_IS_MAP_FIELD_WITH_PROTO_2_ENUM_VALUE_MASK));
    }
  }

  public boolean hasAuxData(boolean isProto2) {
    return isProto2 && isSingular();
  }

  public int id() {
    return id;
  }

  public boolean isGroup() {
    return id == GROUP_ID;
  }

  public boolean isGroupList() {
    return id == GROUP_LIST_ID;
  }

  public boolean isMap() {
    return id == MAP_ID;
  }

  public boolean isMapFieldWithProto2EnumValue() {
    return isMapFieldWithProto2EnumValue;
  }

  public boolean isMessage() {
    return id == MESSAGE_ID;
  }

  public boolean isMessageList() {
    return id == MESSAGE_LIST_ID;
  }

  public boolean isOneOf() {
    return false;
  }

  public ProtoOneOfFieldType asOneOf() {
    return null;
  }

  public boolean isRequired() {
    return isRequired;
  }

  public boolean isSingular() {
    return id <= GROUP_ID;
  }

  public boolean isValid() {
    assert id < FIRST_ONE_OF_ID;
    return true;
  }

  public boolean needsIsInitializedCheck() {
    return needsIsInitializedCheck;
  }

  public int numberOfObjects(boolean isProto2, ProtoFieldTypeFactory factory) {
    switch (id) {
      case MESSAGE_LIST_ID:
      case GROUP_LIST_ID:
        return 2;
      case ENUM_ID:
      case ENUM_LIST_ID:
      case ENUM_LIST_PACKAGED_ID:
        return BooleanUtils.intValue(isProto2) + 1;
      case MAP_ID:
        return BooleanUtils.intValue(isMapFieldWithProto2EnumValue) + 2;
      default:
        return 1;
    }
  }

  public int serialize() {
    int result = id;
    if (isRequired) {
      result |= FIELD_IS_REQUIRED_MASK;
    }
    if (needsIsInitializedCheck) {
      result |= FIELD_NEEDS_IS_INITIALIZED_CHECK_MASK;
    }
    if (isMapFieldWithProto2EnumValue) {
      result |= FIELD_IS_MAP_FIELD_WITH_PROTO_2_ENUM_VALUE_MASK;
    }
    return result;
  }
}
