Adding a product attribute with values and mark one value as default

tl;dr: For select attributes this cannot be declared directly in the initial addAttribute() call; two calls are required.

In order to set the default value, eav_attribute.defaultmust be set with the primary key value from the eav_attribute_option table At a high level the need for two calls is apparent by looking at the flow and function of the addAttribute() and addAttributeOption() methods:

  1. Prepare values
  2. Insert/update into the eav_attribute table
  3. Insert/update set/group
  4. Call addAttributeOption() to insert/update option values

The only hope then would be that addAttributeOption() will be able to update the eav_attribute record. However, there is no code which does this. The only tables accessed by this method are eav_attribute_option and eav_attribute_option_value.

It is therefore necessary to call getAttribute() after the initial addAttribute() call, grab the attribute option ID and then call updateAttribute().

Edit:

After the earlier answer I couldn't help but verify my answer against the existing code; after all, for catalog_product entities we have a nice MVC flow to follow thanks to the attribute CRUD GUI. And there it was, in \Mage_Adminhtml_Catalog_Product_AttributeController::saveAction(), that I saw the attribute model being set with the following data just before being saved:

Option and option configuration data visualized with PhpStorm & Xdebug

Note that the attribute's default value has references to the value keys. Do a little digging and you end up at \Mage_Eav_Model_Resource_Entity_Attribute::_saveOption(), which is called from this resource's _afterSave() method - just as you'd expect given that we need to have an eav_attribute record to update. You can even see how multiselect and select defaults are handled in the same place, just before the final update:

$bind  = array('default_value' => implode(',', $attributeDefaultValue));
$where = array('attribute_id =?' => $object->getId());
$adapter->update($this->getMainTable(), $bind, $where);

So, another alternative is to work directly with the resource model.