/*
 * Copyright (C) 2007 The Android Open Source Project
 *
 * 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
 *
 *      http://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.android.dexgen.dex.file;

import com.android.dexgen.dex.code.DalvCode;
import com.android.dexgen.dex.code.DalvInsnList;
import com.android.dexgen.dex.code.LocalList;
import com.android.dexgen.dex.code.PositionList;
import com.android.dexgen.rop.cst.CstMethodRef;
import com.android.dexgen.rop.cst.CstType;
import com.android.dexgen.rop.cst.CstUtf8;
import com.android.dexgen.util.AnnotatedOutput;
import com.android.dexgen.util.ExceptionWithContext;

import java.io.PrintWriter;

public class DebugInfoItem extends OffsettedItem {
    /** the required alignment for instances of this class */
    private static final int ALIGNMENT = 1;

    private static final boolean ENABLE_ENCODER_SELF_CHECK = false;

    /** {@code non-null;} the code this item represents */
    private final DalvCode code;

    private byte[] encoded;

    private final boolean isStatic;
    private final CstMethodRef ref;

    public DebugInfoItem(DalvCode code, boolean isStatic, CstMethodRef ref) {
        // We don't know the write size yet.
        super (ALIGNMENT, -1);

        if (code == null) {
            throw new NullPointerException("code == null");
        }

        this.code = code;
        this.isStatic = isStatic;
        this.ref = ref;
    }

    /** {@inheritDoc} */
    @Override
    public ItemType itemType() {
        return ItemType.TYPE_DEBUG_INFO_ITEM;
    }

    /** {@inheritDoc} */
    @Override
    public void addContents(DexFile file) {
        // No contents to add.
    }

    /** {@inheritDoc} */
    @Override
    protected void place0(Section addedTo, int offset) {
        // Encode the data and note the size.

        try {
            encoded = encode(addedTo.getFile(), null, null, null, false);
            setWriteSize(encoded.length);
        } catch (RuntimeException ex) {
            throw ExceptionWithContext.withContext(ex,
                    "...while placing debug info for " + ref.toHuman());
        }
    }

    /** {@inheritDoc} */
    @Override
    public String toHuman() {
        throw new RuntimeException("unsupported");
    }

    /**
     * Writes annotations for the elements of this list, as
     * zero-length. This is meant to be used for dumping this instance
     * directly after a code dump (with the real local list actually
     * existing elsewhere in the output).
     *
     * @param file {@code non-null;} the file to use for referencing other sections
     * @param out {@code non-null;} where to annotate to
     * @param prefix {@code null-ok;} prefix to attach to each line of output
     */
    public void annotateTo(DexFile file, AnnotatedOutput out, String prefix) {
        encode(file, prefix, null, out, false);
    }

    /**
     * Does a human-friendly dump of this instance.
     *
     * @param out {@code non-null;} where to dump
     * @param prefix {@code non-null;} prefix to attach to each line of output
     */
    public void debugPrint(PrintWriter out, String prefix) {
        encode(null, prefix, out, null, false);
    }

    /** {@inheritDoc} */
    @Override
    protected void writeTo0(DexFile file, AnnotatedOutput out) {
        if (out.annotates()) {
            /*
             * Re-run the encoder to generate the annotations,
             * but write the bits from the original encode
             */

            out.annotate(offsetString() + " debug info");
            encode(file, null, null, out, true);
        }

        out.write(encoded);
    }

    /**
     * Performs debug info encoding.
     *
     * @param file {@code null-ok;} file to refer to during encoding
     * @param prefix {@code null-ok;} prefix to attach to each line of output
     * @param debugPrint {@code null-ok;} if specified, an alternate output for
     * annotations
     * @param out {@code null-ok;} if specified, where annotations should go
     * @param consume whether to claim to have consumed output for
     * {@code out}
     * @return {@code non-null;} the encoded array
     */
    private byte[] encode(DexFile file, String prefix, PrintWriter debugPrint,
            AnnotatedOutput out, boolean consume) {
        byte[] result = encode0(file, prefix, debugPrint, out, consume);

        if (ENABLE_ENCODER_SELF_CHECK && (file != null)) {
            try {
                DebugInfoDecoder.validateEncode(result, file, ref, code,
                        isStatic);
            } catch (RuntimeException ex) {
                // Reconvert, annotating to System.err.
                encode0(file, "", new PrintWriter(System.err, true), null,
                        false);
                throw ex;
            }
        }

        return result;
    }

    /**
     * Helper for {@link #encode} to do most of the work.
     *
     * @param file {@code null-ok;} file to refer to during encoding
     * @param prefix {@code null-ok;} prefix to attach to each line of output
     * @param debugPrint {@code null-ok;} if specified, an alternate output for
     * annotations
     * @param out {@code null-ok;} if specified, where annotations should go
     * @param consume whether to claim to have consumed output for
     * {@code out}
     * @return {@code non-null;} the encoded array
     */
    private byte[] encode0(DexFile file, String prefix, PrintWriter debugPrint,
            AnnotatedOutput out, boolean consume) {
        PositionList positions = code.getPositions();
        LocalList locals = code.getLocals();
        DalvInsnList insns = code.getInsns();
        int codeSize = insns.codeSize();
        int regSize = insns.getRegistersSize();

        DebugInfoEncoder encoder =
            new DebugInfoEncoder(positions, locals,
                    file, codeSize, regSize, isStatic, ref);

        byte[] result;

        if ((debugPrint == null) && (out == null)) {
            result = encoder.convert();
        } else {
            result = encoder.convertAndAnnotate(prefix, debugPrint, out,
                    consume);
        }

        return result;
    }
}
