from optparse import make_option

from django.core.exceptions import ObjectDoesNotExist, MultipleObjectsReturned
from django.core.management.base import BaseCommand

from amo.utils import chunked
from mkt.developers.providers import Provider
from mkt.developers.utils import uri_to_pk
from mkt.webapps.models import Webapp
from mkt.webpay.utils import make_external_id


def get_generic_product(app):
    if app.app_payment_accounts.exists():
        account = app.app_payment_accounts.all()[:1].get()
        generic_product = Provider.generic.product.get_object(
            seller=uri_to_pk(account.payment_account.seller_uri),
            external_id=make_external_id(app),
        )
        return generic_product


class Command(BaseCommand):
    help = ('Look up and store the Generic Product public_ids'
            ' for existing webapps with configured payment accounts.')
    option_list = BaseCommand.option_list + (
        make_option(
            '--dry-run',
            default=False,
            action='store_true',
            dest='dry_run',
            help='Look up the public_ids in Solitude without saving'),
        )

    def handle(self, *args, **options):
        webapps = (Webapp.objects.filter(app_payment_accounts__isnull=False)
                                 .no_transforms()
                                 .select_related('app_payment_accounts'))
        for chunk in chunked(webapps, 50):
            for app in chunk:
                try:
                    print 'Looking up public_id for', app
                    generic_product = get_generic_product(app)
                    if not generic_product:
                        continue
                    print 'Found public_id', generic_product['public_id']

                    if not options['dry_run']:
                        print 'Saving', app
                        app.solitude_public_id = generic_product['public_id']
                        app.save()
                except (ObjectDoesNotExist, MultipleObjectsReturned), e:
                    print 'Error', e.__class__.__name__, e
                    continue

@@ -448,16 +448,20 @@
     
+for 
 account 
 = ap
@@ -456,17 +456,18 @@
 account 
-=
+in
  app.app
@@ -493,19 +493,258 @@
 ll()
-%5B:1%5D.get()%0A
+:%0A            print (%0A                'Looking up public_id for app '%0A                '%7Bapp%7D using account %7Baccount%7D'%0A            ).format(%0A                app=app,%0A                account=account.payment_account.seller_uri)%0A            try:%0A        
     
@@ -814,16 +814,24 @@
         
+        
 seller=u
@@ -888,16 +888,24 @@
         
+  
+      
 external
@@ -933,28 +933,314 @@
 app)
-,%0A        )%0A
+)%0A                print (%0A                    'Found generic product %7Bproduct%7D for '%0A                    'app %7Bapp%7D using account %7Baccount%7D'%0A                ).format(%0A                    product=generic_product%5B'public_id'%5D,%0A                    app=app,%0A                    account=account)%0A       
         
 retu
@@ -1235,16 +1235,17 @@
         
+ 
 return g
@@ -1259,16 +1259,306 @@
 product%0A
+            except ObjectDoesNotExist:%0A                pass%0A            except MultipleObjectsReturned:%0A                print 'Found multiple generic products for app %7Bapp%7D'.format(%0A                    app=app)%0A        print 'Unable to find a generic product for app %7Bapp%7D'.format(app=app)%0A
 %0A%0Aclass 
@@ -1963,25 +1963,16 @@
 aving'),
-%0A        
 )%0A%0A    d
@@ -2284,91 +2284,8 @@
 nk:%0A
-                try:%0A                    print 'Looking up public_id for', app%0A    
     
@@ -2335,28 +2335,24 @@
 roduct(app)%0A
-    
             
@@ -2391,36 +2391,32 @@
                 
-    
 continue%0A       
@@ -2408,20 +2408,16 @@
 ontinue%0A
-    
         
@@ -2491,28 +2491,24 @@
             
-    
 if not optio
@@ -2538,28 +2538,24 @@
             
-    
 print 'Savin
@@ -2559,19 +2559,19 @@
 ving
+ app
 ', app%0A
-    
     
@@ -2656,28 +2656,24 @@
             
-    
 app.save()%0A 
@@ -2675,165 +2675,4 @@
 e()%0A
-                except (ObjectDoesNotExist, MultipleObjectsReturned), e:%0A                    print 'Error', e.__class__.__name__, e%0A                    continue%0A

Support multiple accounts (bug 1010557)