/*
 * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 */

package jdk.tools.jaotc;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map.Entry;

import jdk.tools.jaotc.binformat.BinaryContainer;
import jdk.tools.jaotc.binformat.ByteContainer;
import jdk.tools.jaotc.binformat.HeaderContainer;
import jdk.tools.jaotc.utils.Timer;
import org.graalvm.compiler.code.CompilationResult;
import org.graalvm.compiler.debug.Debug;
import org.graalvm.compiler.debug.Debug.Scope;
import org.graalvm.compiler.hotspot.HotSpotHostBackend;
import org.graalvm.compiler.hotspot.stubs.Stub;

import jdk.vm.ci.hotspot.HotSpotJVMCIRuntime;
import jdk.vm.ci.hotspot.HotSpotVMConfigStore;
import jdk.vm.ci.hotspot.VMField;

class DataBuilder {

    private final Main main;

    private final HotSpotHostBackend backend;

    private final List<AOTCompiledClass> classes;

    /**
     * Target-independent container in which text symbols and code bytes are created.
     */
    private final BinaryContainer binaryContainer;

    private final HashMap<Long, String> vmAddresses = new HashMap<>();

    public DataBuilder(Main main, HotSpotHostBackend backend, List<AOTCompiledClass> classes, BinaryContainer binaryContainer) {
        this.main = main;
        this.backend = backend;
        this.classes = classes;
        this.binaryContainer = binaryContainer;
        fillVMAddresses(HotSpotJVMCIRuntime.runtime().getConfigStore());
    }

    /**
     * Returns a value-name map of all {@link VMField} fields.
     */
    private void fillVMAddresses(HotSpotVMConfigStore config) {
        for (VMField vmField : config.getFields().values()) {
            if (vmField.value != null) {
                final long address = vmField.value;
                String value = vmField.name;
                /*
                 * Some fields don't contain addresses but integer values. At least don't add zero
                 * entries to avoid matching null addresses.
                 */
                if (address != 0) {
                    vmAddresses.put(address, value);
                }
            }
        }
        for (Entry<String, Long> vmAddress : config.getAddresses().entrySet()) {
            final long address = vmAddress.getValue();
            String value = vmAddress.getKey();
            String old = vmAddresses.put(address, value);
            if (old != null) {
                throw new InternalError("already in map: address: " + address + ", current: " + value + ", old: " + old);
            }
        }
    }

    /**
     * Get the C/C++ function name associated with the foreign call target {@code address}.
     *
     * @param address native address
     * @return C/C++ functio name associated with the native address
     */
    public String getVMFunctionNameForAddress(long address) {
        return vmAddresses.get(address);
    }

    /**
     * Returns the host backend used for this compilation.
     *
     * @return host backend
     */
    public HotSpotHostBackend getBackend() {
        return backend;
    }

    /**
     * Returns the binary container for this compilation.
     *
     * @return binary container
     */
    public BinaryContainer getBinaryContainer() {
        return binaryContainer;
    }

    /**
     * Prepare data with all compiled classes and stubs.
     *
     * @throws Exception
     */
    @SuppressWarnings("try")
    public void prepareData() throws Exception {
        try (Timer t = new Timer(main, "Parsing compiled code")) {
            /*
             * Copy compiled code into code section container and calls stubs (PLT trampoline).
             */
            CodeSectionProcessor codeSectionProcessor = new CodeSectionProcessor(this);
            for (AOTCompiledClass c : classes) {
                // For each class we need 2 GOT slots:
                // first - for initialized klass
                // second - only for loaded klass
                c.addAOTKlassData(binaryContainer);
                codeSectionProcessor.process(c);
            }
        }

        AOTCompiledClass stubCompiledCode = retrieveStubCode();

        // Free memory!
        try (Timer t = main.options.verbose ? new Timer(main, "Freeing memory") : null) {
            main.printMemoryUsage();
            System.gc();
        }

        MetadataBuilder metadataBuilder = null;
        try (Timer t = new Timer(main, "Processing metadata")) {
            /*
             * Generate metadata for compiled code and copy it into metadata section. Create
             * relocation information for all references (call, constants, etc) in compiled code.
             */
            metadataBuilder = new MetadataBuilder(this);
            metadataBuilder.processMetadata(classes, stubCompiledCode);
        }

        // Free memory!
        try (Timer t = main.options.verbose ? new Timer(main, "Freeing memory") : null) {
            main.printMemoryUsage();
            System.gc();
        }

        try (Timer t = new Timer(main, "Preparing stubs binary")) {
            prepareStubsBinary(stubCompiledCode);
        }
        try (Timer t = new Timer(main, "Preparing compiled binary")) {
            // Should be called after Stubs because they can set dependent klasses.
            prepareCompiledBinary(metadataBuilder);
        }
    }

    /**
     * Get all stubs from Graal and add them to the code section.
     */
    @SuppressWarnings("try")
    private AOTCompiledClass retrieveStubCode() {
        ArrayList<CompiledMethodInfo> stubs = new ArrayList<>();
        for (Stub stub : Stub.getStubs()) {
            try (Scope scope = Debug.scope("CompileStubs")) {
                CompilationResult result = stub.getCompilationResult(backend);
                CompiledMethodInfo cm = new CompiledMethodInfo(result, new AOTStub(stub, backend));
                stubs.add(cm);
            } catch (Throwable e) {
                throw Debug.handle(e);
            }
        }
        AOTCompiledClass stubCompiledCode = new AOTCompiledClass(stubs);
        CodeSectionProcessor codeSectionProcessor = new CodeSectionProcessor(this);
        codeSectionProcessor.process(stubCompiledCode);
        return stubCompiledCode;
    }

    /**
     * Prepare metaspace.offsets section.
     */
    private void prepareCompiledBinary(MetadataBuilder metadataBuilder) {
        for (AOTCompiledClass c : classes) {
            // Create records for compiled AOT methods.
            c.putMethodsData(binaryContainer);
        }
        // Create records for compiled AOT classes.
        AOTCompiledClass.putAOTKlassData(binaryContainer);

        // Fill in AOTHeader
        HeaderContainer header = binaryContainer.getHeaderContainer();
        header.setClassesCount(AOTCompiledClass.getClassesCount());
        header.setMethodsCount(CompiledMethodInfo.getMethodsCount());
        // Record size of got sections
        ByteContainer bc = binaryContainer.getMetaspaceGotContainer();
        header.setMetaspaceGotSize((bc.getByteStreamSize() / 8));
        bc = binaryContainer.getMetadataGotContainer();
        header.setMetadataGotSize((bc.getByteStreamSize() / 8));
        bc = binaryContainer.getOopGotContainer();
        header.setOopGotSize((bc.getByteStreamSize() / 8));
    }

    /**
     * Prepare stubs.offsets section.
     */
    private void prepareStubsBinary(AOTCompiledClass compiledClass) {
        // For each of the compiled stubs, create records holding information about
        // them.
        ArrayList<CompiledMethodInfo> compiledStubs = compiledClass.getCompiledMethods();
        int cntStubs = compiledStubs.size();
        binaryContainer.addMethodsCount(cntStubs, binaryContainer.getStubsOffsetsContainer());
        for (CompiledMethodInfo methodInfo : compiledStubs) {
            // Note, stubs have different offsets container.
            methodInfo.addMethodOffsets(binaryContainer, binaryContainer.getStubsOffsetsContainer());
        }
    }

}
