# Copyright 2021 The University of Michigan
# Copyright 2022 Efabless Corporation
#
# 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.

proc insert_buffer {pin_name pin_type master_name net_name inst_name} {
    set db [ord::get_db]
    set block [ord::get_db_block]

    # Create buffer instance
    set master [$db findMaster $master_name]
    if { $master == "NULL" } {
        puts "Buffer cell '$master' not found."
        exit -1
    }

    set inst [odb::dbInst_create $block $master $inst_name]

    # Figure out the inputs & outputs of the master
    foreach mterm [$master getMTerms] {
        if {[$mterm getSigType] == "POWER"} {
            continue
        }
        if {[$mterm getSigType] == "GROUND"} {
            continue
        }
        if {[$mterm getIoType] == "INPUT"} {
            set input $mterm
        }
        if {[$mterm getIoType] == "OUTPUT"} {
            set output $mterm
        }
    }

    # New net to connect to
    set new_net [odb::dbNet_create $block $net_name]

    if {$pin_type=="ITerm"} {
        # Finding the block with pin name
        set iterm [$block findITerm $pin_name]
        if { $iterm == "NULL" } {
            puts "Instance terminal '$pin_name' not found."
            exit -1
        }
        set old_net [$iterm getNet]

        # Original disconnect command
        odb::dbITerm_disconnect $iterm

        # Original connect command
        odb::dbITerm_connect $iterm $new_net

        # Set I/O of iterm (Buffer)
        set in_iterm [$inst getITerm $input]
        set out_iterm [$inst getITerm $output]

        if { ![info exists ::env(INSERT_BUFFER_NO_PLACE)] } {
            # define the instance to which the buffer inserted will connected to
            set master_inst [$iterm getInst]
            # get the geometry of the instance, geometry means its shape, the coordinate of its vertex...
            set box [$master_inst getBBox]

            # get the position of the lower left point of this instance
            set x_min [$box xMin]
            set y_min [$box yMin]

            # $inst is the buffer we want to insert, now insert it in the position of the instance it is connected to,
            # using setLocation, and detail_place will help us separate them
            [$inst setLocation $x_min $y_min]
            [$inst setPlacementStatus PLACED]
        }

        odb::dbITerm_connect $in_iterm $new_net
        odb::dbITerm_connect $out_iterm $old_net

    } else {
        # Finding the block with pin name
        set bterm [$block findBTerm $pin_name]
        set old_net [$bterm getNet]
        set  net_out_iterm [odb::dbNet_get1stITerm $old_net]
        set old_net_inst [$net_out_iterm getInst]
        set net_mterm [$net_out_iterm getMTerm]
        set old_net_input $net_mterm
        odb::dbITerm_disconnect $net_out_iterm

        if { ![info exists ::env(INSERT_BUFFER_NO_PLACE)] } {
            set box [$bterm getBBox]

            # get the position of the lower left point of this instance
            set x_min [$box xMin]
            set y_min [$box yMin]

            # $inst is the buffer we want to insert, now insert it in the position of the instance it is connected to,
            # using setLocation, and detail_place will help us separate them
            [$inst setLocation $x_min $y_min]
            [$inst setPlacementStatus PLACED]
        }

        # Find output/input of buffer iterm
        set in_iterm [$inst getITerm $input]
        set out_iterm [$inst getITerm $output]

        odb::dbITerm_connect $out_iterm $new_net
        odb::dbITerm_connect $net_out_iterm $new_net
        odb::dbITerm_connect $in_iterm $old_net
    }
}

if { [info exists ::env(INSERT_BUFFER_COMMAND) ]} {
    if {[catch {read_lef $::env(MERGED_LEF)} errmsg]} {
        puts stderr $errmsg
        exit 1
    }

    if {[catch {read_def $::env(CURRENT_DEF)} errmsg]} {
        puts stderr $errmsg
        exit 1
    }

    set arg_list [split $::env(INSERT_BUFFER_COMMAND) " "]
    insert_buffer {*}$arg_list

    write_def $::env(SAVE_DEF)
}