// Add VPort to Subnet / Create VPort. Caller must initialize the Subnet ID (s.ID). Additionally, the virtual Port must have:
// - A Name (vp.Name)
// - A Type (vp.Type)
func (s *Subnet) AddVPort(c *nuage.Connection, vp VPort) (VPort, error) {
	var vpa [1]VPort

	// In the worst case we return what we received
	vpa[0] = vp
	if s.ID == "" {
		err := fmt.Errorf("Subnet Add VPort: Empty Subnet ID, nothing to do")
		return vpa[0], err
	}

	//XXX -- TBD: Better sanity checks
	if vp.Name == "" || vp.Type == "" || vp.AddressSpoofing == "" {
		err := fmt.Errorf("Subnet Add VPort: Invalid VPort initialization, nothing to do")
		return vpa[0], err
	}

	jsonvport, _ := json.MarshalIndent(vp, "", "\t")
	reply, err := nuage.CreateEntity(c, "subnets/"+s.ID+"/vports", jsonvport)

	if err != nil {
		log.Debugf("Subnet Add VPort: Error: %s ", err)
		return vpa[0], err
	}

	err = json.Unmarshal(reply, &vpa)
	if err != nil {
		log.Debugf("Subnet Add VPort:  Unable to decode JSON payload: %s ", err)
		return vpa[0], err
	}
	log.Debug("Subnet Add VPort: done")
	return vpa[0], nil

}
// Assumes the method receiver was allocated using "new(Subnet)"
// Caller must populate:
// - Name (s.Name)
// - Parent Zone ID (s.ParentID)
// - Subnet Tempate ID (s.TemplateID)
// - Address (s.Address) -- e.g. "10.24.24.0"
// - Netmask (s.Netmask) -- e.g. "255.255.255.0"
// - Optionally:  Subnet Template ID (s.TemplateID)
func (s *Subnet) Create(c *nuage.Connection) error {
	if s == nil {
		err := fmt.Errorf("Subnet Create: Empty method receiver, nothing to do")
		return err
	}

	if s.Name == "" {
		err := fmt.Errorf("Subnet Create: Empty Name, nothing to do")
		return err
	}

	if s.ParentID == "" {
		err := fmt.Errorf("Subnet Create: Empty ParentID, nothing to do")
		return err
	}

	if s.TemplateID == "" && (s.Address == "" || s.Netmask == "") {
		err := fmt.Errorf("Subnet Create: Need either Subnet Template ID or Subnet Address & Netmask. Nothing to do")
		return err
	}

	// XXX - Do not insist on it being present
	// if s.TemplateID == "" {
	// 	err := fmt.Errorf("Subnet Create: Empty subnet template ID, nothing to do")
	// 	return err
	// }

	// It has to be an array since the reply from the server is as an array of JSON objects, and we use it for decoding as well
	var subneta [1]Subnet
	// XXX - This copies the supplied Name, ParentID and TemplateID
	subneta[0] = *s

	jsonsubnet, _ := json.MarshalIndent(subneta[0], "", "\t")
	reply, err := nuage.CreateEntity(c, "zones/"+s.ParentID+"/subnets", jsonsubnet)
	if err != nil {
		log.Debugf("Subnet Create: Unable to create Subnet with name: [%s] . Error: %s ", s.Name, err)
		return err
	}

	err = json.Unmarshal(reply, &subneta)

	if err != nil {
		log.Debugf("Subnet Create: Unable to decode JSON payload: %s ", err)
		return err
	}

	// XXX - Mutate the receiver
	*s = subneta[0]
	log.Debugf("Subnet Create: Created Subnet with ID: [%s]", s.ID)
	return nil
}
// Assumes that the method receiver was allocated using "new(Enterprise)", initialized accordingly (name + description).
func (org *Enterprise) Create(c *nuage.Connection) error {
	if org == nil {
		err := fmt.Errorf("Enterprise Create: Empty method receiver, nothing to do")
		return err
	}

	// Check that the method receiver was allocated properly
	// Disabled. Overkill ?

	// if reflect.TypeOf(*org).String() != "nuage_v3_2.Enterprise" {
	// 	err := fmt.Errorf("Enterprise Create: Invalid method receiver type")
	// 	return err
	// }

	// It has to be an array since the reply from the server is as an array of JSON objects, and we use it for decoding as well
	var orga [1]Enterprise
	orga[0] = *org

	if org.Description == "" {
		// Default Enterpise Description unless one is specified
		orga[0].Description = "Created by Golang API driver"
	} else {
		orga[0].Description = org.Description
	}

	jsonorg, _ := json.MarshalIndent(orga[0], "", "\t")

	// Quick and dirty alternative: Just build a JSON object with "name" and "description" fields
	// jsonorg := "      {\"name\":\"" + name + "\",\"description\":\"Created by Golang API client\"}      "

	reply, err := nuage.CreateEntity(c, "enterprises", jsonorg)

	if err != nil {
		log.Debugf("Enterprise Create: Unable to create Enterprise with name: %s . Error: %s ", org.Name, err)
		return err
	}

	err = json.Unmarshal(reply, &orga)

	if err != nil {
		log.Debugf("Enterprise Create: Unable to decode JSON payload: %s ", err)
		return err
	}

	// XXX -- Mutate the method receiver
	*org = orga[0]
	log.Debugf("Enterprise Create: Created Enterprise with Name: [%s] and ID: [%s]", org.Name, org.ID)
	return nil

}
// Assumes the method receiver was allocated using "new(Zone)"
// Caller must populate:
// - Name (z.Name)
// - Parent Domain ID (z.ParentID)
// - Optionally:  Zone Template ID (z.TemplateID)
func (z *Zone) Create(c *nuage.Connection) error {
	if z == nil {
		err := fmt.Errorf("Zone Create: Empty method receiver, nothing to do")
		return err
	}

	if z.Name == "" {
		err := fmt.Errorf("Zone Create: Empty Name, nothing to do")
		return err
	}

	if z.ParentID == "" {
		err := fmt.Errorf("Zone Create: Empty ParentID, nothing to do")
		return err
	}

	// XXX - Do not insist on it being present
	// if z.TemplateID == "" {
	// 	err := fmt.Errorf("Zone Create: Empty zone template ID, nothing to do")
	// 	return err
	// }

	// It has to be an array since the reply from the server is as an array of JSON objects, and we use it for decoding as well
	var za [1]Zone
	// XXX - This copies the supplied Name, ParentID and TemplateID
	za[0] = *z

	jsonzone, _ := json.MarshalIndent(za[0], "", "\t")
	reply, err := nuage.CreateEntity(c, "domains/"+z.ParentID+"/zones", jsonzone)

	if err != nil {
		log.Debugf("Zone Create: Unable to create Zone with name: [%s] . Error: %s ", z.Name, err)
		return err
	}

	err = json.Unmarshal(reply, &za)

	if err != nil {
		log.Debugf("Zone Create: Unable to decode JSON payload: %s ", err)
		return err
	}

	// XXX - Mutate the receiver
	*z = za[0]
	log.Debugf("Zone Create: Created Zone with ID: [%s]", z.ID)
	return nil
}
// Assumes the method receiver was allocated using "new(Domain)"
// Caller must populate:
// - Name (d.Name)
// - Parent Enterprise ID (d.ParentID)
// - Domain Template ID (d.TemplateID)
func (d *Domain) Create(c *nuage.Connection) error {
	if d == nil {
		err := fmt.Errorf("Domain Create: Empty method receiver, nothing to do")
		return err
	}

	if d.Name == "" {
		err := fmt.Errorf("Domain Create: Empty Name, nothing to do")
		return err
	}

	if d.ParentID == "" {
		err := fmt.Errorf("Domain Create: Empty ParentID, nothing to do")
		return err
	}

	if d.TemplateID == "" {
		err := fmt.Errorf("Domain Create: Empty domain template ID, nothing to do")
		return err
	}

	// It has to be an array since the reply from the server is as an array of JSON objects, and we use it for decoding as well
	var da [1]Domain
	// XXX - This copies the supplied Name, ParentID and TemplateID
	da[0] = *d

	jsondomain, _ := json.MarshalIndent(da[0], "", "\t")
	reply, err := nuage.CreateEntity(c, "enterprises/"+d.ParentID+"/domains", jsondomain)

	if err != nil {
		log.Debugf("Domain Create: Unable to create Domain with name: [%s] . Error: %s ", d.Name, err)
		return err
	}

	err = json.Unmarshal(reply, &da)

	if err != nil {
		log.Debugf("Domain Create: Unable to decode JSON payload: %s ", err)
		return err
	}

	// XXX - Mutate the receiver
	*d = da[0]
	log.Debugf("Domain Create: Created Domain with ID: [%s]", d.ID)
	return nil
}
// Assumes the method receiver was allocated using "new(Zonetemplate)"
// Caller must populate Name (zt.Name) and ParentID (zt.ParentID)
func (zt *Zonetemplate) Create(c *nuage.Connection) error {
	if zt == nil {
		err := fmt.Errorf("Zone template Create: Empty method receiver, nothing to do")
		return err
	}

	if zt.Name == "" {
		err := fmt.Errorf("Zone template Create: Empty Name, nothing to do")
		return err
	}

	if zt.ParentID == "" {
		err := fmt.Errorf("Zone template Create: Empty ParentID, nothing to do")
		return err
	}

	// It has to be an array since the reply from the server is as an array of JSON objects, and we use it for decoding as well
	var zta [1]Zonetemplate

	// XXX - This copies the supplied Name and ParentID
	zta[0] = *zt

	jsonzt, _ := json.MarshalIndent(zta[0], "", "\t")
	reply, err := nuage.CreateEntity(c, "domaintemplates/"+zt.ParentID+"/zonetemplates", jsonzt)

	if err != nil {
		log.Debugf("Zone template Create: Unable to create Zone template with name: [%s] . Error: %s ", zt.Name, err)
		return err
	}

	err = json.Unmarshal(reply, &zta)

	if err != nil {
		log.Debugf("Zone template Create: Unable to decode JSON payload: %s ", err)
		return err
	}

	// XXX - Mutate the receiver
	*zt = zta[0]
	log.Debugf("Zone template Create: Created Zone template with ID: [%s]", zt.ID)
	return nil
}
// VirtualMachine Create
func (vm *VirtualMachine) Create(c *nuage.Connection) error {
	if vm == nil {
		err := fmt.Errorf("VirtualMachine Create: Empty method receiver, nothing to do")
		return err
	}

	if vm.Name == "" {
		err := fmt.Errorf("VirtualMachine Create: Empty Name, nothing to do")
		return err
	}

	if vm.UUID == "" {
		err := fmt.Errorf("VirtualMachine Create: Empty UUID, nothing to do")
		return err
	}

	// It has to be an array since the reply from the server is as an array of JSON objects, and we use it for decoding as well
	var vma [1]VirtualMachine
	// Copies the method receiver & all initialized fields
	vma[0] = *vm

	jsonvm, _ := json.MarshalIndent(vma[0], "", "\t")
	reply, err := nuage.CreateEntity(c, "vms", jsonvm)

	if err != nil {
		log.Debugf("VirtualMachine Create: Unable to create VirtualMachine with name: [%s] . Error: %s ", vm.Name, err)
		return err
	}

	err = json.Unmarshal(reply, &vma)

	if err != nil {
		log.Debugf("VirtualMachine Create: Unable to decode JSON payload: %s ", err)
		return err
	}

	// XXX - Mutate the receiver
	*vm = vma[0]
	log.Debugf("VirtualMachine Create: Created VirtualMachine with ID: [%s]", vm.ID)
	return nil
}