// Copyright 2020 Google LLC
//
// 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.firebase.encoders.proto;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import com.google.firebase.encoders.EncodingException;
import com.google.firebase.encoders.FieldDescriptor;
import com.google.firebase.encoders.ValueEncoderContext;
import java.io.IOException;

class ProtobufValueEncoderContext implements ValueEncoderContext {
  private boolean encoded = false;
  private boolean skipDefault = false;
  private FieldDescriptor field;
  private final ProtobufDataEncoderContext objEncoderCtx;

  ProtobufValueEncoderContext(ProtobufDataEncoderContext objEncoderCtx) {
    this.objEncoderCtx = objEncoderCtx;
  }

  void resetContext(FieldDescriptor field, boolean skipDefault) {
    this.encoded = false;
    this.field = field;
    this.skipDefault = skipDefault;
  }

  private void checkNotUsed() {
    if (encoded) {
      throw new EncodingException("Cannot encode a second value in the ValueEncoderContext");
    }
    encoded = true;
  }

  @NonNull
  @Override
  public ValueEncoderContext add(@Nullable String value) throws IOException {
    checkNotUsed();
    objEncoderCtx.add(field, value, skipDefault);
    return this;
  }

  @NonNull
  @Override
  public ValueEncoderContext add(float value) throws IOException {
    checkNotUsed();
    objEncoderCtx.add(field, value, skipDefault);
    return this;
  }

  @NonNull
  @Override
  public ValueEncoderContext add(double value) throws IOException {
    checkNotUsed();
    objEncoderCtx.add(field, value, skipDefault);
    return this;
  }

  @NonNull
  @Override
  public ValueEncoderContext add(int value) throws IOException {
    checkNotUsed();
    objEncoderCtx.add(field, value, skipDefault);
    return this;
  }

  @NonNull
  @Override
  public ValueEncoderContext add(long value) throws IOException {
    checkNotUsed();
    objEncoderCtx.add(field, value, skipDefault);
    return this;
  }

  @NonNull
  @Override
  public ValueEncoderContext add(boolean value) throws IOException {
    checkNotUsed();
    objEncoderCtx.add(field, value, skipDefault);
    return this;
  }

  @NonNull
  @Override
  public ValueEncoderContext add(@NonNull byte[] bytes) throws IOException {
    checkNotUsed();
    objEncoderCtx.add(field, bytes, skipDefault);
    return this;
  }
}
