<commit_before>// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
package vix

import (
	"fmt"
	"strings"

	"github.com/cloudescape/govmx"
)

// Device Type
const (
	CDROM_IMAGE string = "cdrom-image"
	CDROM_RAW   string = "cdrom-raw"
)

// CD/DVD configuration
type CDDVDDrive struct {
	ID string
	// Either IDE, SCSI or SATA
	Bus vmx.BusType
	// Used only when attaching image files. Ex: ISO images
	// If you just want to attach a raw cdrom device leave it empty
	Filename string
}

// Attaches a CD/DVD drive to the virtual machine.
func (v *VM) AttachCDDVD(drive *CDDVDDrive) error {
	if running, _ := v.IsRunning(); running {
		return &VixError{
			Operation: "vm.AttachCDDVD",
			Code:      200000,
			Text:      "Virtual machine must be powered off in order to attach a CD/DVD drive.",
		}
	}

	// Loads VMX file in memory
	v.vmxfile.Read()
	model := v.vmxfile.model

	device := vmx.Device{}
	if drive.Filename != "" {
		device.Filename = drive.Filename
		device.Type = CDROM_IMAGE
	} else {
		device.Type = CDROM_RAW
		device.Autodetect = true
	}

	device.Present = true
	device.StartConnected = true

	if drive.Bus == "" {
		drive.Bus = vmx.IDE
	}

	switch drive.Bus {
	case vmx.IDE:
		model.IDEDevices = append(model.IDEDevices, vmx.IDEDevice{Device: device})
	case vmx.SCSI:
		model.SCSIDevices = append(model.SCSIDevices, vmx.SCSIDevice{Device: device})
	case vmx.SATA:
		model.SATADevices = append(model.SATADevices, vmx.SATADevice{Device: device})
	default:
		return &VixError{
			Operation: "vm.AttachCDDVD",
			Code:      200001,
			Text:      fmt.Sprintf("Unrecognized bus type: %s\n", drive.Bus),
		}
	}

	return v.vmxfile.Write()
}

// Detaches a CD/DVD device from the virtual machine
func (v *VM) DetachCDDVD(drive *CDDVDDrive) error {
	if running, _ := v.IsRunning(); running {
		return &VixError{
			Operation: "vm.DetachCDDVD",
			Code:      200002,
			Text:      "Virtual machine must be powered off in order to detach CD/DVD drive.",
		}
	}

	// Loads VMX file in memory
	err := v.vmxfile.Read()
	if err != nil {
		return err
	}

	model := v.vmxfile.model

	switch drive.Bus {
	case vmx.IDE:
		for i, device := range model.IDEDevices {
			if drive.ID == device.VMXID {
				// This method of removing the element avoids memory leaks
				copy(model.IDEDevices[i:], model.IDEDevices[i+1:])
				model.IDEDevices[len(model.IDEDevices)-1] = vmx.IDEDevice{}
				model.IDEDevices = model.IDEDevices[:len(model.IDEDevices)-1]
			}
		}
	case vmx.SCSI:
		for i, device := range model.SCSIDevices {
			if drive.ID == device.VMXID {
				copy(model.SCSIDevices[i:], model.SCSIDevices[i+1:])
				model.SCSIDevices[len(model.SCSIDevices)-1] = vmx.SCSIDevice{}
				model.SCSIDevices = model.SCSIDevices[:len(model.SCSIDevices)-1]
			}
		}
	case vmx.SATA:
		for i, device := range model.SATADevices {
			if drive.ID == device.VMXID {
				copy(model.SATADevices[i:], model.SATADevices[i+1:])
				model.SATADevices[len(model.SATADevices)-1] = vmx.SATADevice{}
				model.SATADevices = model.SATADevices[:len(model.SATADevices)-1]
			}
		}
	default:
		return &VixError{
			Operation: "vm.DetachCDDVD",
			Code:      200003,
			Text:      fmt.Sprintf("Unrecognized bus type: %s\n", drive.Bus),
		}
	}

	return v.vmxfile.Write()
}

// Returns an unordered slice of currently attached CD/DVD devices on any bus.
func (v *VM) CDDVDs() ([]*CDDVDDrive, error) {
	// Loads VMX file in memory
	err := v.vmxfile.Read()
	if err != nil {
		return nil, err
	}

	model := v.vmxfile.model

	var cddvds []*CDDVDDrive
	model.WalkDevices(func(d vmx.Device) {
		var bus vmx.BusType
		switch {
		case strings.HasPrefix(d.VMXID, string(vmx.IDE)):
			bus = vmx.IDE
		case strings.HasPrefix(d.VMXID, string(vmx.SCSI)):
			bus = vmx.SCSI
		case strings.HasPrefix(d.VMXID, string(vmx.SATA)):
			bus = vmx.SATA
		}

		if d.Type == CDROM_IMAGE || d.Type == CDROM_RAW {
			cddvds = append(cddvds, &CDDVDDrive{
				ID:       d.VMXID,<commit_msg>These constants now live in govmx<commit_after>// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
package vix

import (
	"fmt"
	"strings"

	"github.com/cloudescape/govmx"
)

// CD/DVD configuration
type CDDVDDrive struct {
	ID string
	// Either IDE, SCSI or SATA
	Bus vmx.BusType
	// Used only when attaching image files. Ex: ISO images
	// If you just want to attach a raw cdrom device leave it empty
	Filename string
}

// Attaches a CD/DVD drive to the virtual machine.
func (v *VM) AttachCDDVD(drive *CDDVDDrive) error {
	if running, _ := v.IsRunning(); running {
		return &VixError{
			Operation: "vm.AttachCDDVD",
			Code:      200000,
			Text:      "Virtual machine must be powered off in order to attach a CD/DVD drive.",
		}
	}

	// Loads VMX file in memory
	v.vmxfile.Read()
	model := v.vmxfile.model

	device := vmx.Device{}
	if drive.Filename != "" {
		device.Filename = drive.Filename
		device.Type = vmx.CDROM_IMAGE
	} else {
		device.Type = vmx.CDROM_RAW
		device.Autodetect = true
	}

	device.Present = true
	device.StartConnected = true

	if drive.Bus == "" {
		drive.Bus = vmx.IDE
	}

	switch drive.Bus {
	case vmx.IDE:
		model.IDEDevices = append(model.IDEDevices, vmx.IDEDevice{Device: device})
	case vmx.SCSI:
		model.SCSIDevices = append(model.SCSIDevices, vmx.SCSIDevice{Device: device})
	case vmx.SATA:
		model.SATADevices = append(model.SATADevices, vmx.SATADevice{Device: device})
	default:
		return &VixError{
			Operation: "vm.AttachCDDVD",
			Code:      200001,
			Text:      fmt.Sprintf("Unrecognized bus type: %s\n", drive.Bus),
		}
	}

	return v.vmxfile.Write()
}

// Detaches a CD/DVD device from the virtual machine
func (v *VM) DetachCDDVD(drive *CDDVDDrive) error {
	if running, _ := v.IsRunning(); running {
		return &VixError{
			Operation: "vm.DetachCDDVD",
			Code:      200002,
			Text:      "Virtual machine must be powered off in order to detach CD/DVD drive.",
		}
	}

	// Loads VMX file in memory
	err := v.vmxfile.Read()
	if err != nil {
		return err
	}

	model := v.vmxfile.model

	switch drive.Bus {
	case vmx.IDE:
		for i, device := range model.IDEDevices {
			if drive.ID == device.VMXID {
				// This method of removing the element avoids memory leaks
				copy(model.IDEDevices[i:], model.IDEDevices[i+1:])
				model.IDEDevices[len(model.IDEDevices)-1] = vmx.IDEDevice{}
				model.IDEDevices = model.IDEDevices[:len(model.IDEDevices)-1]
			}
		}
	case vmx.SCSI:
		for i, device := range model.SCSIDevices {
			if drive.ID == device.VMXID {
				copy(model.SCSIDevices[i:], model.SCSIDevices[i+1:])
				model.SCSIDevices[len(model.SCSIDevices)-1] = vmx.SCSIDevice{}
				model.SCSIDevices = model.SCSIDevices[:len(model.SCSIDevices)-1]
			}
		}
	case vmx.SATA:
		for i, device := range model.SATADevices {
			if drive.ID == device.VMXID {
				copy(model.SATADevices[i:], model.SATADevices[i+1:])
				model.SATADevices[len(model.SATADevices)-1] = vmx.SATADevice{}
				model.SATADevices = model.SATADevices[:len(model.SATADevices)-1]
			}
		}
	default:
		return &VixError{
			Operation: "vm.DetachCDDVD",
			Code:      200003,
			Text:      fmt.Sprintf("Unrecognized bus type: %s\n", drive.Bus),
		}
	}

	return v.vmxfile.Write()
}

// Returns an unordered slice of currently attached CD/DVD devices on any bus.
func (v *VM) CDDVDs() ([]*CDDVDDrive, error) {
	// Loads VMX file in memory
	err := v.vmxfile.Read()
	if err != nil {
		return nil, err
	}

	model := v.vmxfile.model

	var cddvds []*CDDVDDrive
	model.WalkDevices(func(d vmx.Device) {
		var bus vmx.BusType
		switch {
		case strings.HasPrefix(d.VMXID, string(vmx.IDE)):
			bus = vmx.IDE
		case strings.HasPrefix(d.VMXID, string(vmx.SCSI)):
			bus = vmx.SCSI
		case strings.HasPrefix(d.VMXID, string(vmx.SATA)):
			bus = vmx.SATA
		}

		if d.Type == vmx.CDROM_IMAGE || d.Type == vmx.CDROM_RAW {
			cddvds = append(cddvds, &CDDVDDrive{
				ID:       d.VMXID,
{'fraction_non_alphanumeric': 0.13034875092752907, 'fraction_numerical': 0.009151620084095969, 'mean_word_length': 3.2630469161834474, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '689113', 'n_tokens_mistral': 3466, 'n_tokens_neox': 3122, 'n_words': 759}