// Copyright (c) 2020, 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.desugar.desugaredlibrary.gson;

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.TypeAdapter;
import com.google.gson.reflect.TypeToken;
import com.google.gson.stream.JsonReader;
import com.google.gson.stream.JsonToken;
import com.google.gson.stream.JsonWriter;
import java.io.IOException;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.Objects;
import java.util.Optional;

public class OptionalTestClass {
  static class Data {
    final int id;
    final String name;

    Data(int id, String name) {
      this.id = id;
      this.name = name;
    }

    @Override
    public boolean equals(Object o) {
      if (this == o) return true;
      if (!(o instanceof Data)) return false;
      Data data = (Data) o;
      return id == data.id && name.equals(data.name);
    }

    @Override
    public int hashCode() {
      return Objects.hash(id, name);
    }

    @Override
    public String toString() {
      return "Data{" + "id=" + id + ", name='" + name + '\'' + '}';
    }
  }

  static class OptionalAdapter<T> extends TypeAdapter<Optional<T>> {
    private final TypeAdapter<T> delegate;

    public OptionalAdapter(TypeAdapter<T> delegate) {
      this.delegate = delegate;
    }

    @Override
    public void write(JsonWriter out, Optional<T> value) throws IOException {
      if (!value.isPresent()) {
        out.nullValue();
        return;
      }
      delegate.write(out, value.get());
    }

    @Override
    public Optional<T> read(JsonReader in) throws IOException {
      if (in.peek() == JsonToken.NULL) {
        in.nextNull();
        return Optional.empty();
      }
      return Optional.of(delegate.read(in));
    }

    @SuppressWarnings("unchecked")
    public static OptionalAdapter getInstance(TypeToken typeToken) {
      TypeAdapter delegate;
      Type type = typeToken.getType();
      assert type instanceof ParameterizedType;
      Type innerType = ((ParameterizedType) type).getActualTypeArguments()[0];
      delegate = new Gson().getAdapter(TypeToken.get(innerType));
      return new OptionalAdapter<>(delegate);
    }
  }

  public static void main(String[] args) {
    GsonBuilder builder = new GsonBuilder();
    builder.registerTypeAdapter(
        Optional.class, OptionalAdapter.getInstance(new TypeToken<Optional<Data>>() {}));
    Gson gson = builder.create();
    Optional<Data> optionalData = Optional.of(new Data(1, "a"));
    String optionalDataSerialized = gson.toJson(optionalData);
    Optional<Data> optionalDataDeserialized = gson.fromJson(optionalDataSerialized, Optional.class);
    System.out.println(optionalData.getClass() == optionalDataDeserialized.getClass());
    System.out.println(optionalData.equals(optionalDataDeserialized));
  }
}
