/*
 * Copyright (c) 2017-present, Facebook, Inc.
 * All rights reserved.
 *
 * This source code is licensed under the BSD-style license found in the
 * LICENSE file in the root directory of this source tree. An additional grant
 * of patent rights can be found in the PATENTS file in the same directory.
 */

package com.facebook.litho.specmodels.model;

import com.facebook.litho.annotations.ResType;
import com.squareup.javapoet.AnnotationSpec;
import com.squareup.javapoet.TypeName;
import java.lang.annotation.Annotation;
import java.util.List;
import javax.annotation.concurrent.Immutable;

/**
 * Model that is an abstract representation of a {@link com.facebook.litho.annotations.InjectProp}.
 */
@Immutable
public class InjectPropModel implements MethodParamModel {
  private final MethodParamModel mParamModel;
  private final boolean mIsLazy;

  public InjectPropModel(MethodParamModel paramModel, boolean isLazy) {
    mParamModel = paramModel;
    mIsLazy = isLazy;
  }

  @Override
  public TypeSpec getTypeSpec() {
    return mParamModel.getTypeSpec();
  }

  @Override
  public TypeName getTypeName() {
    return mParamModel.getTypeName();
  }

  @Override
  public String getName() {
    return mParamModel.getName();
  }

  @Override
  public List<Annotation> getAnnotations() {
    return mParamModel.getAnnotations();
  }

  @Override
  public List<AnnotationSpec> getExternalAnnotations() {
    return mParamModel.getExternalAnnotations();
  }

  @Override
  public Object getRepresentedObject() {
    return mParamModel.getRepresentedObject();
  }

  @Override
  public boolean equals(Object o) {
    if (o instanceof InjectPropModel) {
      final InjectPropModel p = (InjectPropModel) o;
      return mParamModel.equals(p.mParamModel);
    }

    return false;
  }

  @Override
  public int hashCode() {
    return mParamModel.hashCode();
  }

  /** Convert to a regular prop model. */
  public PropModel toPropModel() {
    final String localName = getName();
    return new PropModel(mParamModel, false, ResType.NONE, "") {
      @Override
      public String getName() {
        return localName;
      }
    };
  }

  public boolean isLazy() {
    return mIsLazy;
  }

  /** @return a new {@link PropModel} instance with the given name overridden. */
  public InjectPropModel withName(String name) {
    return new InjectPropModel(mParamModel, mIsLazy) {
      @Override
      public String getName() {
        return name;
      }
    };
  }
}

@@ -542,16 +542,42 @@
 l.List;%0A
+import java.util.Objects;%0A
 import j
@@ -1650,51 +1650,98 @@
 if (
-o instanceof InjectPropModel) %7B%0A      final
+this == o) return true;%0A    if (o == null %7C%7C getClass() != o.getClass()) return false;%0A   
  Inj
@@ -1753,17 +1753,20 @@
 opModel 
-p
+that
  = (Inje
@@ -1785,26 +1785,24 @@
  o;%0A    
-  
 return m
 ParamMod
@@ -1797,26 +1797,57 @@
 rn m
-ParamModel
+IsLazy == that.mIsLazy &&%0A        Objects
 .equals(
 p.mP
@@ -1842,18 +1842,16 @@
 .equals(
-p.
 mParamMo
@@ -1857,34 +1857,27 @@
 odel
-);%0A    %7D%0A%0A    return false
+, that.mParamModel)
 ;%0A  
@@ -1920,32 +1920,45 @@
 () %7B%0A    return 
+Objects.hash(
 mParamModel.hash
@@ -1956,18 +1956,17 @@
 odel
-.hashCode(
+, mIsLazy
 );%0A 

Fix object contract for lazy field in InjectPropModel