from booking.models import Booking
 from workflow.models import WorkflowStep, AbstractSelectOrCreate
-from workflow.forms import ResourceSelectorForm, SWConfigSelectorForm, BookingMetaForm
-from resource_inventory.models import GenericResourceBundle, ConfigBundle
+from workflow.forms import ResourceSelectorForm, SWConfigSelectorForm, BookingMetaForm, OPNFVSelectForm
+from resource_inventory.models import GenericResourceBundle, ConfigBundle, OPNFVConfig
 
 
 """
         }
 
 
+class OPNFV_EnablePicker(object):
+    pass
+
+
+class OPNFV_Select(AbstractSelectOrCreate, OPNFV_EnablePicker):
+    title = "Choose an OPNFV Config"
+    description = "Choose or create a description of how you want to deploy OPNFV"
+    short_title = "opnfv config"
+    form = OPNFVSelectForm
+    enabled = False
+
+    def __init__(self, *args, **kwargs):
+        super().__init__(*args, **kwargs)
+        self.select_repo_key = self.repo.SELECTED_OPNFV_CONFIG
+        self.confirm_key = "booking"
+
+    def alert_bundle_missing(self):
+        self.set_invalid("Please select a valid OPNFV config")
+
+    def get_form_queryset(self):
+        cb = self.repo_get(self.repo.SELECTED_CONFIG_BUNDLE)
+        qs = OPNFVConfig.objects.filter(bundle=cb)
+        return qs
+
+    def put_confirm_info(self, config):
+        confirm_dict = self.repo_get(self.repo.CONFIRMATION)
+        if self.confirm_key not in confirm_dict:
+            confirm_dict[self.confirm_key] = {}
+        confirm_dict[self.confirm_key]["OPNFV Configuration"] = config.name
+        self.repo_put(self.repo.CONFIRMATION, confirm_dict)
+
+    def get_page_context(self):
+        return {
+            'select_type': 'opnfv',
+            'select_type_title': 'OPNFV Config',
+            'addable_type_num': 4
+        }
+
+
 class Booking_Meta(WorkflowStep):
     template = 'booking/steps/booking_meta.html'
     title = "Extra Info"
             for key in ['length', 'project', 'purpose']:
                 confirm['booking'][key] = form.cleaned_data[key]
 
+            if form.cleaned_data["deploy_opnfv"]:
+                self.repo_get(self.repo.SESSION_MANAGER).set_step_statuses(OPNFV_EnablePicker, desired_enabled=True)
+            else:
+                self.repo_get(self.repo.SESSION_MANAGER).set_step_statuses(OPNFV_EnablePicker, desired_enabled=False)
+
             userprofile_list = form.cleaned_data['users']
             confirm['booking']['collaborators'] = []
             for userprofile in userprofile_list:
 
         items = {}
 
         for bundle in queryset:
-            item = {}
-            item['small_name'] = bundle.name
-            item['expanded_name'] = bundle.owner.username
-            item['string'] = bundle.description
-            item['id'] = bundle.id
-            items[bundle.id] = item
+            items[bundle.id] = {
+                'small_name': bundle.name,
+                'expanded_name': bundle.owner.username,
+                'string': bundle.description,
+                'id': bundle.id
+            }
+
+        return items
+
+
+class OPNFVSelectForm(SearchableSelectAbstractForm):
+    def generate_items(self, queryset):
+        items = {}
+
+        for config in queryset:
+            items[config.id] = {
+                'small_name': config.name,
+                'expanded_name': config.bundle.owner.username,
+                'string': config.description,
+                'id': config.id
+            }
 
         return items
 
         items = {}
 
         for bundle in queryset:
-            item = {}
-            item['small_name'] = bundle.name
-            item['expanded_name'] = bundle.owner.username
-            item['string'] = bundle.description
-            item['id'] = bundle.id
-            items[bundle.id] = item
+            items[bundle.id] = {
+                'small_name': bundle.name,
+                'expanded_name': bundle.owner.username,
+                'string': bundle.description,
+                'id': bundle.id
+            }
 
         return items
 
     purpose = forms.CharField(max_length=1000)
     project = forms.CharField(max_length=400)
     info_file = forms.CharField(max_length=1000, required=False)
+    deploy_opnfv = forms.BooleanField(required=False)
 
     def __init__(self, *args, user_initial=[], owner=None, **kwargs):
         super(BookingMetaForm, self).__init__(**kwargs)
 
 
 
 from django.forms import formset_factory
-from django.contrib import messages
 
-import json
-
-from workflow.models import WorkflowStep
+from workflow.models import WorkflowStep, AbstractSelectOrCreate
 from resource_inventory.models import ConfigBundle, OPNFV_SETTINGS
 from workflow.forms import OPNFVSelectionForm, OPNFVNetworkRoleForm, OPNFVHostRoleForm, SWConfigSelectorForm, BasicMetaForm
 
 
-class OPNFV_Resource_Select(WorkflowStep):
-    template = 'booking/steps/swconfig_select.html'
+class OPNFV_Resource_Select(AbstractSelectOrCreate):
     title = "Select Software Configuration"
-    description = "Choose the software and related configurations you want to use to configure OPNFV"
-    short_title = "software configuration"
-    modified_key = "configbundle_step"
+    description = "Choose the software bundle you wish to use as a base for your OPNFV configuration"
+    short_title = "software config"
+    form = SWConfigSelectorForm
 
-    def update_confirmation(self):
-        confirm = self.repo_get(self.repo.CONFIRMATION, {})
-        config_bundle = self.repo_get(self.repo.OPNFV_MODELS, {}).get("configbundle")
-        if not config_bundle:
-            return
-        confirm['software bundle'] = config_bundle.name
-        confirm['hardware POD'] = config_bundle.bundle.name
-        self.repo_put(self.repo.CONFIRMATION, confirm)
+    def __init__(self, *args, **kwargs):
+        super().__init__(*args, **kwargs)
+        self.select_repo_key = self.repo.SELECTED_CONFIG_BUNDLE
 
-    def post_render(self, request):
-        models = self.repo_get(self.repo.OPNFV_MODELS, {})
-        form = SWConfigSelectorForm(request.POST)
-        if form.is_valid():
-            bundle_json = form.cleaned_data['software_bundle']
-            bundle_json = bundle_json[2:-2]  # Stupid django string bug
-            if not bundle_json:
-                self.set_invalid("Please select a valid config")
-                return self.render(request)
-            bundle_json = json.loads(bundle_json)
-            if len(bundle_json) < 1:
-                self.set_invalid("Please select a valid config")
-                return self.render(request)
-            bundle = None
-            id = int(bundle_json[0]['id'])
-            bundle = ConfigBundle.objects.get(id=id)
-
-            models['configbundle'] = bundle
-            self.repo_put(self.repo.OPNFV_MODELS, models)
-            self.set_valid("Step Completed")
-            messages.add_message(request, messages.SUCCESS, 'Form Validated Successfully', fail_silently=True)
-            self.update_confirmation()
-        else:
-            self.set_invalid("Please select or create a valid config")
-            messages.add_message(request, messages.ERROR, "Form Didn't Validate", fail_silently=True)
-
-        return self.render(request)
-
-    def get_context(self):
-        context = super(OPNFV_Resource_Select, self).get_context()
-        default = []
+    def get_form_queryset(self):
         user = self.repo_get(self.repo.SESSION_USER)
-
-        context['form'] = SWConfigSelectorForm(chosen_software=default, bundle=None, edit=True, resource=None, user=user)
-        return context
+        qs = ConfigBundle.objects.filter(owner=user)
+        return qs
+
+    def put_confirm_info(self, bundle):
+        confirm_dict = self.repo_get(self.repo.CONFIRMATION)
+        confirm_dict['software bundle'] = bundle.name
+        confirm_dict['hardware POD'] = bundle.bundle.name
+        self.repo_put(self.repo.CONFIRMATION, confirm_dict)
+
+    def get_page_context(self):
+        return {
+            'select_type': 'swconfig',
+            'select_type_title': 'Software Config',
+            'addable_type_num': 2
+        }
 
 
 class Pick_Installer(WorkflowStep):
     def get_context(self):
         context = super(Pick_Installer, self).get_context()
 
-        models = self.repo_get(self.repo.OPNFV_MODELS, None)
+        models = self.repo_get(self.repo.OPNFV_MODELS, {})
         initial = {
             "installer": models.get("installer_chosen"),
             "scenario": models.get("scenario_chosen")
 
     def get_context(self):
         context = super(Assign_Network_Roles, self).get_context()
-        config_bundle = self.repo_get(self.repo.OPNFV_MODELS, {}).get("configbundle")
+        config_bundle = self.repo_get(self.repo.SELECTED_CONFIG_BUNDLE)
         if config_bundle is None:
             context["unavailable"] = True
             return context
 
     def post_render(self, request):
         models = self.repo_get(self.repo.OPNFV_MODELS, {})
-        config_bundle = models.get("configbundle")
+        config_bundle = self.repo_get(self.repo.SELECTED_CONFIG_BUNDLE)
         roles = OPNFV_SETTINGS.NETWORK_ROLES
         net_role_formset = self.create_netformset(roles, config_bundle, data=request.POST)
         if net_role_formset.is_valid():
 
     def get_context(self):
         context = super(Assign_Host_Roles, self).get_context()
-        models = self.repo_get(self.repo.OPNFV_MODELS, {})
-        config = models.get("configbundle")
+        config = self.repo_get(self.repo.SELECTED_CONFIG_BUNDLE)
         if config is None:
             context['error'] = "Please select a Configuration on the first step"