/*
 * Copyright 2012, Google Inc.
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met:
 *
 *     * Redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer.
 *     * Redistributions in binary form must reproduce the above
 * copyright notice, this list of conditions and the following disclaimer
 * in the documentation and/or other materials provided with the
 * distribution.
 *     * Neither the name of Google Inc. nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

package org.jf.dexlib2.util;

import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Maps;
import org.jf.dexlib2.AccessFlags;
import org.jf.dexlib2.Opcodes;
import org.jf.dexlib2.iface.ClassDef;
import org.jf.dexlib2.iface.Method;
import org.jf.dexlib2.iface.MethodImplementation;
import org.jf.dexlib2.iface.instruction.Instruction;
import org.jf.dexlib2.iface.instruction.ReferenceInstruction;
import org.jf.dexlib2.iface.reference.MethodReference;
import org.jf.dexlib2.iface.reference.Reference;

import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.util.List;
import java.util.Map;

public class SyntheticAccessorResolver {
    public static final int METHOD = 0;
    public static final int GETTER = 1;
    public static final int SETTER = 2;
    public static final int POSTFIX_INCREMENT = 3;
    public static final int PREFIX_INCREMENT = 4;
    public static final int POSTFIX_DECREMENT = 5;
    public static final int PREFIX_DECREMENT = 6;
    public static final int ADD_ASSIGNMENT = 7;
    public static final int SUB_ASSIGNMENT = 8;
    public static final int MUL_ASSIGNMENT = 9;
    public static final int DIV_ASSIGNMENT = 10;
    public static final int REM_ASSIGNMENT = 11;
    public static final int AND_ASSIGNMENT = 12;
    public static final int OR_ASSIGNMENT = 13;
    public static final int XOR_ASSIGNMENT = 14;
    public static final int SHL_ASSIGNMENT = 15;
    public static final int SHR_ASSIGNMENT = 16;
    public static final int USHR_ASSIGNMENT = 17;

    private final SyntheticAccessorFSM syntheticAccessorFSM;
    private final Map<String, ClassDef> classDefMap;
    private final Map<String, AccessedMember> resolvedAccessors = Maps.newConcurrentMap();

    public SyntheticAccessorResolver(@Nonnull Opcodes opcodes, @Nonnull Iterable<? extends ClassDef> classDefs) {
        this.syntheticAccessorFSM = new SyntheticAccessorFSM(opcodes);
        ImmutableMap.Builder<String, ClassDef> builder = ImmutableMap.builder();

        for (ClassDef classDef: classDefs) {
            builder.put(classDef.getType(), classDef);
        }

        this.classDefMap = builder.build();
    }

    public static boolean looksLikeSyntheticAccessor(String methodName) {
        return methodName.startsWith("access$");
    }

    @Nullable
    public AccessedMember getAccessedMember(@Nonnull MethodReference methodReference) {
        String methodDescriptor = ReferenceUtil.getMethodDescriptor(methodReference);

        AccessedMember accessedMember = resolvedAccessors.get(methodDescriptor);
        if (accessedMember != null) {
            return accessedMember;
        }

        String type = methodReference.getDefiningClass();
        ClassDef classDef = classDefMap.get(type);
        if (classDef == null) {
            return null;
        }

        Method matchedMethod = null;
        MethodImplementation matchedMethodImpl = null;
        for (Method method: classDef.getMethods()) {
            MethodImplementation methodImpl = method.getImplementation();
            if (methodImpl != null) {
                if (methodReferenceEquals(method, methodReference)) {
                    matchedMethod = method;
                    matchedMethodImpl = methodImpl;
                    break;
                }
            }
        }

        if (matchedMethod == null) {
            return null;
        }

        //A synthetic accessor will be marked synthetic
        if (!AccessFlags.SYNTHETIC.isSet(matchedMethod.getAccessFlags())) {
            return null;
        }

        List<Instruction> instructions = ImmutableList.copyOf(matchedMethodImpl.getInstructions());


        int accessType = syntheticAccessorFSM.test(instructions);

        if (accessType >= 0) {
            AccessedMember member =
                    new AccessedMember(accessType, ((ReferenceInstruction)instructions.get(0)).getReference());
            resolvedAccessors.put(methodDescriptor, member);
            return member;
        }
        return null;
    }

    public static class AccessedMember {
        public final int accessedMemberType;
        @Nonnull public final Reference accessedMember;

        public AccessedMember(int accessedMemberType, @Nonnull Reference accessedMember) {
            this.accessedMemberType = accessedMemberType;
            this.accessedMember = accessedMember;
        }
    }

    private static boolean methodReferenceEquals(@Nonnull MethodReference ref1, @Nonnull MethodReference ref2) {
        // we already know the containing class matches
        return ref1.getName().equals(ref2.getName()) &&
               ref1.getReturnType().equals(ref2.getReturnType()) &&
               ref1.getParameterTypes().equals(ref2.getParameterTypes());
    }
}
