/**
 * Copyright (c) 2013 itemis AG (http://www.itemis.eu) and others.
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Public License 2.0 which is available at
 * http://www.eclipse.org/legal/epl-2.0.
 * 
 * SPDX-License-Identifier: EPL-2.0
 */
package org.eclipse.xtend.lib.annotations;

import com.google.common.annotations.Beta;
import com.google.common.base.Objects;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.function.Consumer;
import org.eclipse.xtend.lib.annotations.FinalFieldsConstructorProcessor;
import org.eclipse.xtend.lib.macro.TransformationContext;
import org.eclipse.xtend.lib.macro.TransformationParticipant;
import org.eclipse.xtend.lib.macro.declaration.AnnotationReference;
import org.eclipse.xtend.lib.macro.declaration.AnnotationTarget;
import org.eclipse.xtend.lib.macro.declaration.EnumerationValueDeclaration;
import org.eclipse.xtend.lib.macro.declaration.FieldDeclaration;
import org.eclipse.xtend.lib.macro.declaration.MethodDeclaration;
import org.eclipse.xtend.lib.macro.declaration.MutableClassDeclaration;
import org.eclipse.xtend.lib.macro.declaration.MutableFieldDeclaration;
import org.eclipse.xtend.lib.macro.declaration.MutableMemberDeclaration;
import org.eclipse.xtend.lib.macro.declaration.MutableMethodDeclaration;
import org.eclipse.xtend.lib.macro.declaration.MutableParameterDeclaration;
import org.eclipse.xtend.lib.macro.declaration.TypeReference;
import org.eclipse.xtend.lib.macro.declaration.Visibility;
import org.eclipse.xtend2.lib.StringConcatenation;
import org.eclipse.xtend2.lib.StringConcatenationClient;
import org.eclipse.xtext.xbase.lib.CollectionLiterals;
import org.eclipse.xtext.xbase.lib.Conversions;
import org.eclipse.xtext.xbase.lib.Extension;
import org.eclipse.xtext.xbase.lib.Functions.Function1;
import org.eclipse.xtext.xbase.lib.IterableExtensions;
import org.eclipse.xtext.xbase.lib.ListExtensions;
import org.eclipse.xtext.xbase.lib.Procedures.Procedure1;
import org.eclipse.xtext.xbase.lib.Pure;
import org.eclipse.xtext.xbase.lib.StringExtensions;

/**
 * @since 2.7
 * @noextend
 * @noreference
 */
@Beta
@SuppressWarnings("all")
public class AccessorsProcessor implements TransformationParticipant<MutableMemberDeclaration> {
  /**
   * @since 2.7
   * @noextend
   * @noreference
   */
  @Beta
  public static class Util {
    @Extension
    private TransformationContext context;
    
    public Util(final TransformationContext context) {
      this.context = context;
    }
    
    public Visibility toVisibility(final AccessorType type) {
      Visibility _switchResult = null;
      if (type != null) {
        switch (type) {
          case PUBLIC_GETTER:
            _switchResult = Visibility.PUBLIC;
            break;
          case PROTECTED_GETTER:
            _switchResult = Visibility.PROTECTED;
            break;
          case PACKAGE_GETTER:
            _switchResult = Visibility.DEFAULT;
            break;
          case PRIVATE_GETTER:
            _switchResult = Visibility.PRIVATE;
            break;
          case PUBLIC_SETTER:
            _switchResult = Visibility.PUBLIC;
            break;
          case PROTECTED_SETTER:
            _switchResult = Visibility.PROTECTED;
            break;
          case PACKAGE_SETTER:
            _switchResult = Visibility.DEFAULT;
            break;
          case PRIVATE_SETTER:
            _switchResult = Visibility.PRIVATE;
            break;
          default:
            StringConcatenation _builder = new StringConcatenation();
            _builder.append("Cannot convert ");
            _builder.append(type);
            throw new IllegalArgumentException(_builder.toString());
        }
      } else {
        StringConcatenation _builder = new StringConcatenation();
        _builder.append("Cannot convert ");
        _builder.append(type);
        throw new IllegalArgumentException(_builder.toString());
      }
      return _switchResult;
    }
    
    public boolean hasGetter(final FieldDeclaration it) {
      final Function1<String, Boolean> _function = (String name) -> {
        MethodDeclaration _findDeclaredMethod = it.getDeclaringType().findDeclaredMethod(name);
        return Boolean.valueOf((_findDeclaredMethod != null));
      };
      return IterableExtensions.<String>exists(this.getPossibleGetterNames(it), _function);
    }
    
    public boolean shouldAddGetter(final FieldDeclaration it) {
      return ((!this.hasGetter(it)) && (this.getGetterType(it) != AccessorType.NONE));
    }
    
    @SuppressWarnings("unchecked")
    public AccessorType getGetterType(final FieldDeclaration it) {
      AnnotationReference _elvis = null;
      AnnotationReference _accessorsAnnotation = this.getAccessorsAnnotation(it);
      if (_accessorsAnnotation != null) {
        _elvis = _accessorsAnnotation;
      } else {
        AnnotationReference _accessorsAnnotation_1 = this.getAccessorsAnnotation(it.getDeclaringType());
        _elvis = _accessorsAnnotation_1;
      }
      final AnnotationReference annotation = _elvis;
      if ((annotation != null)) {
        final Function1<EnumerationValueDeclaration, AccessorType> _function = (EnumerationValueDeclaration it_1) -> {
          return AccessorType.valueOf(it_1.getSimpleName());
        };
        final List<AccessorType> types = ListExtensions.<EnumerationValueDeclaration, AccessorType>map(((List<EnumerationValueDeclaration>)Conversions.doWrapArray(annotation.getEnumArrayValue("value"))), _function);
        AccessorType _elvis_1 = null;
        final Function1<AccessorType, Boolean> _function_1 = (AccessorType it_1) -> {
          return Boolean.valueOf(it_1.name().endsWith("GETTER"));
        };
        AccessorType _findFirst = IterableExtensions.<AccessorType>findFirst(types, _function_1);
        if (_findFirst != null) {
          _elvis_1 = _findFirst;
        } else {
          _elvis_1 = AccessorType.NONE;
        }
        return _elvis_1;
      }
      return null;
    }
    
    public AnnotationReference getAccessorsAnnotation(final AnnotationTarget it) {
      return it.findAnnotation(this.context.findTypeGlobally(Accessors.class));
    }
    
    public AnnotationReference getDeprecatedAnnotation(final AnnotationTarget it) {
      return it.findAnnotation(this.context.findTypeGlobally(Deprecated.class));
    }
    
    public AccessorsDeprecationPolicy getDeprecationPolicyAsEnum(final AnnotationReference annot) {
      return AccessorsDeprecationPolicy.valueOf(annot.getEnumValue("deprecationPolicy").getSimpleName());
    }
    
    public Object validateGetter(final MutableFieldDeclaration field) {
      return null;
    }
    
    public String getGetterName(final FieldDeclaration it) {
      return IterableExtensions.<String>head(this.getPossibleGetterNames(it));
    }
    
    public List<String> getPossibleGetterNames(final FieldDeclaration it) {
      final ArrayList<String> names = CollectionLiterals.<String>newArrayList();
      if ((((this.isBooleanType(this.orObject(it.getType())) && it.getSimpleName().startsWith("is")) && (it.getSimpleName().length() > 2)) && Character.isUpperCase(it.getSimpleName().charAt(2)))) {
        String _simpleName = it.getSimpleName();
        names.add(_simpleName);
      }
      List<String> _xifexpression = null;
      boolean _isBooleanType = this.isBooleanType(this.orObject(it.getType()));
      if (_isBooleanType) {
        _xifexpression = Collections.<String>unmodifiableList(CollectionLiterals.<String>newArrayList("is", "get"));
      } else {
        _xifexpression = Collections.<String>unmodifiableList(CollectionLiterals.<String>newArrayList("get"));
      }
      final Function1<String, String> _function = (String prefix) -> {
        String _firstUpper = StringExtensions.toFirstUpper(it.getSimpleName());
        return (prefix + _firstUpper);
      };
      names.addAll(ListExtensions.<String, String>map(_xifexpression, _function));
      return names;
    }
    
    public boolean isBooleanType(final TypeReference it) {
      return ((!it.isInferred()) && Objects.equal(it, this.context.getPrimitiveBoolean()));
    }
    
    public void addGetter(final MutableFieldDeclaration field, final Visibility visibility) {
      this.validateGetter(field);
      field.markAsRead();
      final Procedure1<MutableMethodDeclaration> _function = (MutableMethodDeclaration it) -> {
        this.context.setPrimarySourceElement(it, this.context.getPrimarySourceElement(field));
        it.addAnnotation(this.context.newAnnotationReference(Pure.class));
        final Iterable<? extends MethodDeclaration> superGetters = it.getOverriddenOrImplementedMethods();
        boolean _isEmpty = IterableExtensions.isEmpty(superGetters);
        boolean _not = (!_isEmpty);
        if (_not) {
          final Function1<MethodDeclaration, Boolean> _function_1 = (MethodDeclaration it_1) -> {
            return Boolean.valueOf(it_1.isFinal());
          };
          boolean _exists = IterableExtensions.exists(superGetters, _function_1);
          if (_exists) {
            StringConcatenation _builder = new StringConcatenation();
            _builder.append("Adding a getter to the field ");
            String _simpleName = field.getSimpleName();
            _builder.append(_simpleName);
            _builder.append(" would override a final method.");
            this.context.addError(field, _builder.toString());
          } else {
            it.addAnnotation(this.context.newAnnotationReference(Override.class));
          }
        }
        final AnnotationReference annot = this.getAccessorsAnnotation(field);
        if ((annot != null)) {
          AccessorsDeprecationPolicy _deprecationPolicyAsEnum = this.getDeprecationPolicyAsEnum(annot);
          if (_deprecationPolicyAsEnum != null) {
            switch (_deprecationPolicyAsEnum) {
              case ALWAYS:
              case ONLY_GETTER:
                it.addAnnotation(this.context.newAnnotationReference(Deprecated.class));
                break;
              case SAME_AS_FIELD:
                AnnotationReference _deprecatedAnnotation = this.getDeprecatedAnnotation(field);
                boolean _tripleNotEquals = (_deprecatedAnnotation != null);
                if (_tripleNotEquals) {
                  it.addAnnotation(this.context.newAnnotationReference(Deprecated.class));
                }
                break;
              case ONLY_SETTER:
              case NEVER:
                break;
              default:
                StringConcatenation _builder_1 = new StringConcatenation();
                _builder_1.append("Cannot determine deprecation policy for field ");
                String _simpleName_1 = field.getSimpleName();
                _builder_1.append(_simpleName_1);
                throw new IllegalArgumentException(_builder_1.toString());
            }
          } else {
            StringConcatenation _builder_1 = new StringConcatenation();
            _builder_1.append("Cannot determine deprecation policy for field ");
            String _simpleName_1 = field.getSimpleName();
            _builder_1.append(_simpleName_1);
            throw new IllegalArgumentException(_builder_1.toString());
          }
        }
        it.setReturnType(this.orObject(field.getType()));
        StringConcatenationClient _client = new StringConcatenationClient() {
          @Override
          protected void appendTo(StringConcatenationClient.TargetStringConcatenation _builder) {
            _builder.append("return ");
            Object _fieldOwner = Util.this.fieldOwner(field);
            _builder.append(_fieldOwner);
            _builder.append(".");
            String _simpleName = field.getSimpleName();
            _builder.append(_simpleName);
            _builder.append(";");
          }
        };
        it.setBody(_client);
        it.setStatic(field.isStatic());
        it.setVisibility(visibility);
      };
      field.getDeclaringType().addMethod(this.getGetterName(field), _function);
    }
    
    @SuppressWarnings("unchecked")
    public AccessorType getSetterType(final FieldDeclaration it) {
      AnnotationReference _elvis = null;
      AnnotationReference _accessorsAnnotation = this.getAccessorsAnnotation(it);
      if (_accessorsAnnotation != null) {
        _elvis = _accessorsAnnotation;
      } else {
        AnnotationReference _accessorsAnnotation_1 = this.getAccessorsAnnotation(it.getDeclaringType());
        _elvis = _accessorsAnnotation_1;
      }
      final AnnotationReference annotation = _elvis;
      if ((annotation != null)) {
        final Function1<EnumerationValueDeclaration, AccessorType> _function = (EnumerationValueDeclaration it_1) -> {
          return AccessorType.valueOf(it_1.getSimpleName());
        };
        final List<AccessorType> types = ListExtensions.<EnumerationValueDeclaration, AccessorType>map(((List<EnumerationValueDeclaration>)Conversions.doWrapArray(annotation.getEnumArrayValue("value"))), _function);
        AccessorType _elvis_1 = null;
        final Function1<AccessorType, Boolean> _function_1 = (AccessorType it_1) -> {
          return Boolean.valueOf(it_1.name().endsWith("SETTER"));
        };
        AccessorType _findFirst = IterableExtensions.<AccessorType>findFirst(types, _function_1);
        if (_findFirst != null) {
          _elvis_1 = _findFirst;
        } else {
          _elvis_1 = AccessorType.NONE;
        }
        return _elvis_1;
      }
      return null;
    }
    
    private Object fieldOwner(final MutableFieldDeclaration it) {
      Object _xifexpression = null;
      boolean _isStatic = it.isStatic();
      if (_isStatic) {
        _xifexpression = this.context.newTypeReference(it.getDeclaringType());
      } else {
        _xifexpression = "this";
      }
      return _xifexpression;
    }
    
    public boolean hasSetter(final FieldDeclaration it) {
      MethodDeclaration _findDeclaredMethod = it.getDeclaringType().findDeclaredMethod(this.getSetterName(it), this.orObject(it.getType()));
      return (_findDeclaredMethod != null);
    }
    
    public String getSetterName(final FieldDeclaration it) {
      String _firstUpper = StringExtensions.toFirstUpper(it.getSimpleName());
      return ("set" + _firstUpper);
    }
    
    public boolean shouldAddSetter(final FieldDeclaration it) {
      return (((!it.isFinal()) && (!this.hasSetter(it))) && (this.getSetterType(it) != AccessorType.NONE));
    }
    
    public void validateSetter(final MutableFieldDeclaration field) {
      boolean _isFinal = field.isFinal();
      if (_isFinal) {
        this.context.addError(field, "Cannot set a final field");
      }
      if (((field.getType() == null) || field.getType().isInferred())) {
        this.context.addError(field, "Type cannot be inferred.");
        return;
      }
    }
    
    public void addSetter(final MutableFieldDeclaration field, final Visibility visibility) {
      this.validateSetter(field);
      final Procedure1<MutableMethodDeclaration> _function = (MutableMethodDeclaration it) -> {
        this.context.setPrimarySourceElement(it, this.context.getPrimarySourceElement(field));
        it.setReturnType(this.context.getPrimitiveVoid());
        final Iterable<? extends MethodDeclaration> superSetters = it.getOverriddenOrImplementedMethods();
        boolean _isEmpty = IterableExtensions.isEmpty(superSetters);
        boolean _not = (!_isEmpty);
        if (_not) {
          final Function1<MethodDeclaration, Boolean> _function_1 = (MethodDeclaration it_1) -> {
            return Boolean.valueOf(it_1.isFinal());
          };
          boolean _exists = IterableExtensions.exists(superSetters, _function_1);
          if (_exists) {
            StringConcatenation _builder = new StringConcatenation();
            _builder.append("Adding a setter to the field ");
            String _simpleName = field.getSimpleName();
            _builder.append(_simpleName);
            _builder.append(" would override a final method.");
            this.context.addError(field, _builder.toString());
          } else {
            it.addAnnotation(this.context.newAnnotationReference(Override.class));
          }
        }
        final AnnotationReference annot = this.getAccessorsAnnotation(field);
        if ((annot != null)) {
          AccessorsDeprecationPolicy _deprecationPolicyAsEnum = this.getDeprecationPolicyAsEnum(annot);
          if (_deprecationPolicyAsEnum != null) {
            switch (_deprecationPolicyAsEnum) {
              case ALWAYS:
              case ONLY_SETTER:
                it.addAnnotation(this.context.newAnnotationReference(Deprecated.class));
                break;
              case SAME_AS_FIELD:
                AnnotationReference _deprecatedAnnotation = this.getDeprecatedAnnotation(field);
                boolean _tripleNotEquals = (_deprecatedAnnotation != null);
                if (_tripleNotEquals) {
                  it.addAnnotation(this.context.newAnnotationReference(Deprecated.class));
                }
                break;
              case ONLY_GETTER:
              case NEVER:
                break;
              default:
                StringConcatenation _builder_1 = new StringConcatenation();
                _builder_1.append("Cannot determine deprecation policy for field ");
                String _simpleName_1 = field.getSimpleName();
                _builder_1.append(_simpleName_1);
                throw new IllegalArgumentException(_builder_1.toString());
            }
          } else {
            StringConcatenation _builder_1 = new StringConcatenation();
            _builder_1.append("Cannot determine deprecation policy for field ");
            String _simpleName_1 = field.getSimpleName();
            _builder_1.append(_simpleName_1);
            throw new IllegalArgumentException(_builder_1.toString());
          }
        }
        final MutableParameterDeclaration param = it.addParameter(field.getSimpleName(), this.orObject(field.getType()));
        StringConcatenationClient _client = new StringConcatenationClient() {
          @Override
          protected void appendTo(StringConcatenationClient.TargetStringConcatenation _builder) {
            Object _fieldOwner = Util.this.fieldOwner(field);
            _builder.append(_fieldOwner);
            _builder.append(".");
            String _simpleName = field.getSimpleName();
            _builder.append(_simpleName);
            _builder.append(" = ");
            String _simpleName_1 = param.getSimpleName();
            _builder.append(_simpleName_1);
            _builder.append(";");
          }
        };
        it.setBody(_client);
        it.setStatic(field.isStatic());
        it.setVisibility(visibility);
      };
      field.getDeclaringType().addMethod(this.getSetterName(field), _function);
    }
    
    private TypeReference orObject(final TypeReference ref) {
      TypeReference _xifexpression = null;
      if ((ref == null)) {
        _xifexpression = this.context.getObject();
      } else {
        _xifexpression = ref;
      }
      return _xifexpression;
    }
  }
  
  @Override
  public void doTransform(final List<? extends MutableMemberDeclaration> elements, @Extension final TransformationContext context) {
    final Consumer<MutableMemberDeclaration> _function = (MutableMemberDeclaration it) -> {
      this.transform(it, context);
    };
    elements.forEach(_function);
  }
  
  protected void _transform(final MutableFieldDeclaration it, @Extension final TransformationContext context) {
    @Extension
    final AccessorsProcessor.Util util = new AccessorsProcessor.Util(context);
    final AnnotationReference annot = util.getAccessorsAnnotation(it);
    boolean _shouldAddGetter = util.shouldAddGetter(it);
    if (_shouldAddGetter) {
      util.addGetter(it, util.toVisibility(util.getGetterType(it)));
    } else {
      if (((annot != null) && (util.getDeprecationPolicyAsEnum(annot) == AccessorsDeprecationPolicy.ONLY_GETTER))) {
        StringConcatenation _builder = new StringConcatenation();
        _builder.append("Field ");
        String _simpleName = it.getSimpleName();
        _builder.append(_simpleName);
        _builder.append(" needs no getter, but deprecationPolicy is ONLY_GETTER.");
        _builder.newLineIfNotEmpty();
        _builder.append("Explicitly setting it has no effect, as no getter will be generated.");
        _builder.newLine();
        _builder.append("Use deprecation policy NEVER to disable accessors deprecation and remove this warning.");
        _builder.newLine();
        context.addWarning(it, _builder.toString());
      }
    }
    boolean _shouldAddSetter = util.shouldAddSetter(it);
    if (_shouldAddSetter) {
      util.addSetter(it, util.toVisibility(util.getSetterType(it)));
    } else {
      if (((annot != null) && (util.getDeprecationPolicyAsEnum(annot) == AccessorsDeprecationPolicy.ONLY_SETTER))) {
        StringConcatenation _builder_1 = new StringConcatenation();
        _builder_1.append("Field ");
        String _simpleName_1 = it.getSimpleName();
        _builder_1.append(_simpleName_1);
        _builder_1.append(" needs no setter, but deprecationPolicy is ONLY_SETTER.");
        _builder_1.newLineIfNotEmpty();
        _builder_1.append("Explicitly setting it has no effect, as no setter will be generated.");
        _builder_1.newLine();
        _builder_1.append("Use deprecation policy NEVER to disable accessors deprecation and remove this warning.");
        _builder_1.newLine();
        context.addWarning(it, _builder_1.toString());
      }
    }
  }
  
  protected void _transform(final MutableClassDeclaration it, @Extension final TransformationContext context) {
    AnnotationReference _findAnnotation = it.findAnnotation(context.findTypeGlobally(Data.class));
    boolean _tripleNotEquals = (_findAnnotation != null);
    if (_tripleNotEquals) {
      return;
    }
    @Extension
    final FinalFieldsConstructorProcessor.Util requiredArgsUtil = new FinalFieldsConstructorProcessor.Util(context);
    if ((requiredArgsUtil.needsFinalFieldConstructor(it) || (it.findAnnotation(context.findTypeGlobally(FinalFieldsConstructor.class)) != null))) {
      requiredArgsUtil.addFinalFieldsConstructor(it);
    }
    final Function1<MutableFieldDeclaration, Boolean> _function = (MutableFieldDeclaration it_1) -> {
      return Boolean.valueOf(((!it_1.isStatic()) && context.isThePrimaryGeneratedJavaElement(it_1)));
    };
    final Consumer<MutableFieldDeclaration> _function_1 = (MutableFieldDeclaration it_1) -> {
      this._transform(it_1, context);
    };
    IterableExtensions.filter(it.getDeclaredFields(), _function).forEach(_function_1);
  }
  
  public void transform(final MutableMemberDeclaration it, final TransformationContext context) {
    if (it instanceof MutableClassDeclaration) {
      _transform((MutableClassDeclaration)it, context);
      return;
    } else if (it instanceof MutableFieldDeclaration) {
      _transform((MutableFieldDeclaration)it, context);
      return;
    } else {
      throw new IllegalArgumentException("Unhandled parameter types: " +
        Arrays.<Object>asList(it, context).toString());
    }
  }
}
