#!/usr/bin/env ruby

# Copyright (C) 2011 Apple 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:
# 1. Redistributions of source code must retain the above copyright
#    notice, this list of conditions and the following disclaimer.
# 2. 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.
#
# THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS 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 APPLE INC. OR ITS 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.

$: << File.dirname(__FILE__)

require "config"
require "backends"
require "digest/sha1"
require "offsets"
require "parser"
require "self_hash"
require "settings"
require "transform"

IncludeFile.processIncludeOptions()

inputFlnm = ARGV.shift
outputFlnm = ARGV.shift

validBackends = canonicalizeBackendNames(ARGV.shift.split(/[,\s]+/))
includeOnlyBackends(validBackends)

def emitMagicNumber
    OFFSET_MAGIC_NUMBERS.each {
        | number |
        $output.puts "unsigned(#{number}),"
    }
end

inputHash = "// offlineasm input hash: #{parseHash(inputFlnm)} #{selfHash}"

if FileTest.exist? outputFlnm
    File.open(outputFlnm, "r") {
        | inp |
        firstLine = inp.gets
        if firstLine and firstLine.chomp == inputHash
            $stderr.puts "offlineasm: Nothing changed."
            exit 0
        end
    }
end

originalAST = parse(inputFlnm)

#
# Optimize the AST to make configuration extraction faster. This reduces the AST to a form
# that only contains the things that matter for our purposes: offsets, sizes, and if
# statements.
#

class Node
    def offsetsPruneTo(sequence)
        children.each {
            | child |
            child.offsetsPruneTo(sequence)
        }
    end
    
    def offsetsPrune
        result = Sequence.new(codeOrigin, [])
        offsetsPruneTo(result)
        result
    end
end

class IfThenElse
    def offsetsPruneTo(sequence)
        ifThenElse = IfThenElse.new(codeOrigin, predicate, thenCase.offsetsPrune)
        ifThenElse.elseCase = elseCase.offsetsPrune
        sequence.list << ifThenElse
    end
end

class StructOffset
    def offsetsPruneTo(sequence)
        sequence.list << self
    end
end

class Sizeof
    def offsetsPruneTo(sequence)
        sequence.list << self
    end
end

class ConstExpr
    def offsetsPruneTo(sequence)
        sequence.list << self
    end
end

prunedAST = originalAST.offsetsPrune

File.open(outputFlnm, "w") {
    | outp |
    $output = outp
    outp.puts inputHash
    length = 0

    emitCodeInAllConfigurations(prunedAST) {
        | settings, ast, backend, index |
        constsList = ast.filter(ConstExpr).uniq.sort

        constsList.each_with_index {
            | const, index |
            outp.puts "constexpr int64_t constValue#{index} = static_cast<int64_t>(#{const.value});"
        }
    }

    emitCodeInAllConfigurations(prunedAST) {
        | settings, ast, backend, index |
        offsetsList = ast.filter(StructOffset).uniq.sort
        sizesList = ast.filter(Sizeof).uniq.sort
        constsList = ast.filter(ConstExpr).uniq.sort
        length += OFFSET_HEADER_MAGIC_NUMBERS.size + (OFFSET_MAGIC_NUMBERS.size + 1) * (1 + offsetsList.size + sizesList.size + constsList.size)
    }
    outp.puts "static const int64_t extractorTable[#{length}] = {"
    emitCodeInAllConfigurations(prunedAST) {
        | settings, ast, backend, index |
        OFFSET_HEADER_MAGIC_NUMBERS.each {
            | number |
            $output.puts "unsigned(#{number}),"
        }

        offsetsList = ast.filter(StructOffset).uniq.sort
        sizesList = ast.filter(Sizeof).uniq.sort
        constsList = ast.filter(ConstExpr).uniq.sort

        emitMagicNumber
        outp.puts "#{index},"
        offsetsList.each {
            | offset |
            emitMagicNumber
            outp.puts "OFFLINE_ASM_OFFSETOF(#{offset.struct}, #{offset.field}),"
        }
        sizesList.each {
            | sizeof |
            emitMagicNumber
            outp.puts "sizeof(#{sizeof.struct}),"
        }
        constsList.each_index {
            | index |
            emitMagicNumber
            outp.puts "constValue#{index},"
        }
    }
    outp.puts "};"

}
