#!/usr/bin/env ruby

# -------------------------------------------------------------------------- #
# Copyright 2002-2021, OpenNebula Project, OpenNebula Systems                #
#                                                                            #
# 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.                                             #
#--------------------------------------------------------------------------- #

require 'open3'
require 'base64'
require 'rexml/document'

require_relative '../../command'

#----------------------------------------------------------------------------
# Constants and helper functions
#----------------------------------------------------------------------------
def command(cmd)
    if VNMMAD::VNMNetwork::COMMANDS.key?(cmd.to_sym)
        cmd_str = (VNMMAD::VNMNetwork::COMMANDS[cmd.to_sym]).to_s
    else
        cmd_str = cmd.to_s
    end

    cmd_str
end

vnmad = File.basename(File.expand_path('..', File.dirname(__FILE__)))

XPATH_NICS = "//TEMPLATE/NIC[VN_MAD='#{vnmad}']"
XPATH_HV   = '//HISTORY/VM_MAD'

OVS_VN_MADS = %w[ovswitch ovswitch_vxlan]

#----------------------------------------------------------------------------

template64 = STDIN.read
deploy_id  = ARGV[0]

template = REXML::Document.new(Base64.decode64(template64))

hypervisor = template.elements[XPATH_HV].text

exit 0 if hypervisor != 'firecracker'

if deploy_id.nil? || deploy_id.empty?
    vm_id     = template.elements['/VM/ID'].text
    deploy_id = "one-#{vm_id}"
end

rc = nil

template.elements.each(XPATH_NICS) do |nic_element|
    nic_id  = Integer(nic_element.elements['NIC_ID'].text)
    bridge  = nic_element.elements['BRIDGE'].text

    if_name = "#{deploy_id}-#{nic_id}"

    # check if interface is already defined
    cmd = "#{command(:ip_unpriv)} link show #{if_name}"
    _, _, rc = Open3.capture3(cmd)

    next if rc.success?

    # create tap device
    cmd = "#{command(:ip)} tuntap add #{if_name} mode tap"
    _, _, rc = Open3.capture3(cmd)

    break unless rc.success?

    # set tap interface up
    cmd = "#{command(:ip)} link set #{if_name} up"
    _, _, rc = Open3.capture3(cmd)

    break unless rc.success?

    # Add tap interface to the bridge
    if OVS_VN_MADS.include?(vnmad)
        cmd = "#{command(:ovs_vsctl)} add-port #{bridge} #{if_name}"
    else
        cmd = "#{command(:ip)} link set #{if_name} master #{bridge}"
    end

    _, _, rc = Open3.capture3(cmd)

    break unless rc.success?
end

exit(-1) unless rc.nil? || rc.success?
