# per request at https://www.wikidata.org/w/index.php?title=Wikidata:Bot_requests&diff=859910624&oldid=859827568
import pywikibot
import re
from pywikibot.exceptions import NoPage

commons_site = pywikibot.Site('commons', 'commons')
wikidata_site = pywikibot.Site('wikidata', 'wikidata')
repo = wikidata_site.data_repository()

inputdata = []
with open('./inputdata.txt') as fh: # from https://quarry.wmflabs.org/query/33471
    for line in fh:
        inputdata.append('Category:{}'.format(line.strip().replace('_', ' ')))

catTitlePattern = re.compile('^Category:Maps of (.*)$')

# SELECT * WHERE { ?item wdt:P279* wd:Q4167836 }
categoryTypes = [ 'Q4167836', 'Q1474116', 'Q15407973', 'Q15647814', 'Q24571879', 'Q24574745', 'Q30432511', 'Q54662266', 'Q56428020', 'Q59541917', 'Q59542487', 'Q61029068', 'Q20769287', 'Q23894233', 'Q24046192', 'Q24514938', 'Q30330522', 'Q38084761', 'Q58118449', 'Q20010800', 'Q13331174', 'Q23894246' ]

limit = None

for i, pageTitle in enumerate(inputdata):
    page = pywikibot.Page(commons_site, pageTitle)
    
    print()
    print('{:5d}/{:5d}: {}'.format(i+1, len(inputdata), page.title()))
    
    result = catTitlePattern.search(page.title())
    if result.lastindex == None or result.lastindex == 0: # page from input with wrong naming scheme
        print('* Input category "{}" does not comply with "Maps of" naming scheme'.format(page.title()))
        continue
    categoryCandidate = result.group(1)
    
    genericCategory = None
    categories = page.categories()
    for category in categories:
        if 'Category:{}'.format(categoryCandidate) == category.title():
            genericCategory = category
            break
        
    if genericCategory == None:
        print('* No generic supercategory found for "{}"'.format(page.title()))
        continue
        
    try:
        Qitem = pywikibot.ItemPage.fromPage(genericCategory)
    except NoPage as e:
        print('* No Wikidata item for generic supercategory "{}" found'.format(genericCategory.title()))
        continue
            
    if not Qitem.claims:
        print('* Generic supercategory item {} does not have claims'.format(Qitem.title()))
        continue
    
    catItem = False
    mainItem = None
    if 'P31' in Qitem.claims:
        for claim in Qitem.claims['P31']:
            if claim.getTarget().title() in categoryTypes:
                print('* Generic supercategory item {} has category type ({})'.format(Qitem.title(), claim.getTarget().title()))
                catItem = True
                if 'P301' in Qitem.claims and len(Qitem.claims['P301']) == 1:
                    mainItem = Qitem.claims['P301'][0].getTarget()
                    print('* Main topic item {} for generic supercategory item {} found'.format(mainItem.title(), Qitem.title()))
                
    newP3722Claim = pywikibot.Claim(repo, 'P3722')
    newP3722Claim.setTarget(value=pageTitle[9:])
    
    if catItem == True:
        if mainItem == None:
            print('* No main item found for generic supercategory item {}'.format(Qitem.title()))
            continue
        
        mainItem.get()
        if not mainItem.claims:
            print('* Main item {} of generic supercategory item {} does not have claims'.format(Qitem.title()))
            continue
        if 'P373' not in mainItem.claims:
            print('* Main item {} of generic supercategory item {} does not have a P373 claim'.format(mainItem.title(), Qitem.title()))
            continue
        if len(mainItem.claims['P373']) != 1:
            print('* Main item {} of generic supercategory item {} has wrong number of P373 claims ({})'.format(mainItem.title(), Qitem.title(), len(mainItem.claims['P373'])))
            continue
        if mainItem.claims['P373'][0].getTarget() != categoryCandidate:
            print('* Main item {} of generic supercategory item {} has wrong P373 value "{}" (expected "{}")'.format(mainItem.title(), Qitem.title(), mainItem.claims['P373'][0].getTarget(), categoryCandidate))
            continue
        if 'P3722' in mainItem.claims:
            print('* Main item {} of generic supercategory item {} does already have a P3722 claim'.format(mainItem.title(), Qitem.title()))
            continue
            
        mainItem.addClaim(newP3722Claim)
        print('* Imported for {}: {} --> P3722 --> "{}"'.format(Qitem.title(), mainItem.title(), newP3722Claim.getTarget()))
        
    else:
        if 'P373' not in Qitem.claims:
            print('* Generic supercategory item {} does not have a P373 claim'.format(Qitem.title()))
            continue
        if len(Qitem.claims['P373']) != 1:
            print('* Generic supercategory item {} has wrong number of P373 claims ({})'.format(Qitem.title(), len(Qitem.claims['P373'])))
            continue
        if Qitem.claims['P373'][0].getTarget() != categoryCandidate:
            print('* Generic supercategory item {} has wrong P373 value "{}" (expected "{}")'.format(Qitem.title(), Qitem.claims['P373'][0].getTarget(), categoryCandidate))
            continue 
        if 'P3722' in Qitem.claims:
            print('* Generic supercategory item {} does already have a P3722 claim'.format(Qitem.title()))
            continue

        Qitem.addClaim(newP3722Claim)
        print('* Imported {} --> P3722 --> "{}"'.format(Qitem.title(), newP3722Claim.getTarget()))
        
    if limit != None and i+1 >= limit:
        break