/*
 * Copyright 2019 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
 *
 *     https://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.android.gnd.persistence.local.room;

import androidx.annotation.NonNull;
import androidx.room.ColumnInfo;
import androidx.room.Entity;
import androidx.room.PrimaryKey;

import com.google.android.gms.maps.model.LatLngBounds;
import com.google.android.gnd.model.basemap.Area;
import com.google.auto.value.AutoValue;

import static com.google.android.gnd.persistence.local.room.LatLngBoundsConverter.boundsFromString;
import static com.google.android.gnd.persistence.local.room.LatLngBoundsConverter.boundsToString;

/** Represents a {@link Area} in the local data store. */
@AutoValue
@Entity(tableName = "area")
public abstract class AreaEntity {
  public static Area toArea(AreaEntity areaEntity) {
    Area.Builder area =
        Area.newBuilder()
            .setBounds(boundsFromString(areaEntity.getId()))
            .setState(toAreaState(areaEntity.getState()))
            .setId(areaEntity.getId());
    return area.build();
  }

  private static Area.State toAreaState(AreaEntityState state) {
    switch (state) {
      case PENDING:
        return Area.State.PENDING;
      case IN_PROGRESS:
        return Area.State.IN_PROGRESS;
      case DOWNLOADED:
        return Area.State.DOWNLOADED;
      case FAILED:
        return Area.State.FAILED;
      default:
        throw new IllegalArgumentException("Unknown area state: " + state);
    }
  }

  // The Bounds conversion methods bellow double as type converters so that we can query areas
  // by bounds.

  public static AreaEntity fromArea(Area area) {
    AreaEntity.Builder entity =
        AreaEntity.builder()
            .setId(area.getId())
            .setState(toEntityState(area.getState()))
            .setBounds(boundsToString(area.getBounds()));
    return entity.build();
  }

  private static AreaEntityState toEntityState(Area.State state) {
    switch (state) {
      case PENDING:
        return AreaEntityState.PENDING;
      case IN_PROGRESS:
        return AreaEntityState.IN_PROGRESS;
      case FAILED:
        return AreaEntityState.FAILED;
      case DOWNLOADED:
        return AreaEntityState.DOWNLOADED;
      default:
        return AreaEntityState.UNKNOWN;
    }
  }

  public static AreaEntity create(String id, AreaEntityState state, LatLngBounds bounds) {
    return builder().setId(id).setState(state).setBounds(boundsToString(bounds)).build();
  }

  public static Builder builder() {
    return new AutoValue_AreaEntity.Builder();
  }

  @AutoValue.CopyAnnotations
  @NonNull
  @PrimaryKey
  @ColumnInfo(name = "id")
  public abstract String getId();

  @AutoValue.CopyAnnotations
  @NonNull
  @ColumnInfo(name = "state")
  public abstract AreaEntityState getState();

  @AutoValue.CopyAnnotations
  @NonNull
  @ColumnInfo(name = "bounds")
  public abstract String getBounds();

  @AutoValue.Builder
  public abstract static class Builder {
    public abstract Builder setId(String newId);

    public abstract Builder setState(AreaEntityState newState);

    public abstract Builder setBounds(String bounds);

    public abstract AreaEntity build();
  }
}

@@ -1253,16 +1253,365 @@
 ntity %7B%0A
+  @AutoValue.CopyAnnotations%0A  @NonNull%0A  @PrimaryKey%0A  @ColumnInfo(name = %22id%22)%0A  public abstract String getId();%0A%0A  @AutoValue.CopyAnnotations%0A  @NonNull%0A  @ColumnInfo(name = %22state%22)%0A  public abstract AreaEntityState getState();%0A%0A  @AutoValue.CopyAnnotations%0A  @NonNull%0A  @ColumnInfo(name = %22bounds%22)%0A  public abstract LatLngBounds getBounds();%0A%0A
   public
@@ -1732,25 +1732,8 @@
 nds(
-boundsFromString(
 area
@@ -1742,20 +1742,23 @@
 tity.get
-Id()
+Bounds(
 ))%0A     
@@ -2304,120 +2304,8 @@
  %7D%0A%0A
-  // The Bounds conversion methods bellow double as type converters so that we can query areas%0A  // by bounds.%0A%0A
   pu
@@ -2520,31 +2520,16 @@
 tBounds(
-boundsToString(
 area.get
@@ -2537,17 +2537,16 @@
 ounds())
-)
 ;%0A    re
@@ -3088,16 +3088,23 @@
 uilder()
+%0A      
 .setId(i
@@ -3105,16 +3105,23 @@
 etId(id)
+%0A      
 .setStat
@@ -3128,16 +3128,23 @@
 e(state)
+%0A      
 .setBoun
@@ -3156,25 +3156,16 @@
 unds
-ToString(bounds))
+)%0A      
 .bui
@@ -3267,351 +3267,8 @@
  %7D%0A%0A
-  @AutoValue.CopyAnnotations%0A  @NonNull%0A  @PrimaryKey%0A  @ColumnInfo(name = %22id%22)%0A  public abstract String getId();%0A%0A  @AutoValue.CopyAnnotations%0A  @NonNull%0A  @ColumnInfo(name = %22state%22)%0A  public abstract AreaEntityState getState();%0A%0A  @AutoValue.CopyAnnotations%0A  @NonNull%0A  @ColumnInfo(name = %22bounds%22)%0A  public abstract String getBounds();%0A%0A
   @A
@@ -3325,16 +3325,17 @@
 ilder %7B%0A
+%0A
     publ
@@ -3483,16 +3483,25 @@
 nds(
-String b
+LatLngBounds newB
 ound

Fix create constructor in AreaEntity