# Python Version: 3.x
import onlinejudge
import onlinejudge.implementation.utils as utils
import onlinejudge.implementation.logging as log
import sys
import time
import shutil
import subprocess

default_url_opener = [ 'sensible-browser', 'xdg-open', 'open' ]

def submit(args):
    # parse url
    problem = onlinejudge.dispatch.problem_from_url(args.url)
    if problem is None:
        sys.exit(1)

    # read code
    with open(args.file) as fh:
        code = fh.buffer.read()
    try:
        s = code.decode() # for logging
    except UnicodeDecodeError as e:
        log.failure('%s: %s', e.__class__.__name__, str(e))
        s = repr(code)[ 1 : ]
    log.info('code:')
    log.emit(log.bold(s))

    # prepare kwargs
    kwargs = {}
    if problem.get_service().get_name() == 'topcoder':
        if args.full_submission:
            kwargs['kind'] = 'full'
        else:
            kwargs['kind'] = 'example'

    with utils.with_cookiejar(utils.new_default_session(), path=args.cookie) as sess:
        # language
        langs = problem.get_language_dict(session=sess)

        if args.language not in langs:
            matched_language = search_matched_language(args.language, langs)
            if len(matched_language) == 1:
                args.language = matched_language[0]
                log.info('choosed language: %s', matched_language)
            elif not matched_language:
                log.error('language is unknown')
                log.info('supported languages are:')
                for lang in sorted(langs.keys()):
                    log.emit('%s (%s)', lang, langs[lang]['description'])
                sys.exit(1)
            else:
                log.error('Matched languages were not narrowed down to one.')
                log.info('You have to choose:')
                for lang in sorted(matched_language):
                    log.emit('%s', lang)
                sys.exit(1)

        # confirm
        if args.wait:
            log.status('sleep(%.2f)', args.wait)
            time.sleep(args.wait)
        if not args.yes:
            sys.stdout.write('Are you sure? [y/N] ')
            sys.stdout.flush()
            c = sys.stdin.read(1)
            if c != 'y':
                log.info('terminated.')
                return

        # submit
        submission = problem.submit(code, language=args.language, session=sess, **kwargs)

        # show result
        if submission is None:
            log.failure('submission failed')
        else:
            if args.open:
                if not isinstance(args.open, str):
                    args.open = None
                    for browser in default_url_opener:
                        args.open = shutil.which(browser)
                        if args.open:
                            break
                if not args.open:
                    log.failure('couldn\'t open the url. please specify a browser')
                else:
                    log.info('open the submission page with: %s', args.open)
                    subprocess.check_call([ args.open, submission.get_url() ], stdin=sys.stdin, stdout=sys.stdout, stderr=sys.stderr)

def search_matched_language(language, language_dict):
    # Search partial matched language name (not case sensitive)
    if language is None:
        return []

    matched_language = []
    for supported_lang in language_dict.values():
        if language.lower() in supported_lang['description'].lower():
            matched_language.append(supported_lang['description'])
    return matched_language

@@ -1142,21 +1142,25 @@
 lang
-uage = search
+_ids = get_ids_of
 _mat
@@ -1172,16 +1172,17 @@
 language
+s
 (args.la
@@ -1227,20 +1227,20 @@
 hed_lang
-uage
+_ids
 ) == 1:%0A
@@ -1283,20 +1283,20 @@
 hed_lang
-uage
+_ids
 %5B0%5D%0A    
@@ -1341,27 +1341,66 @@
 : %25s
-', matched_language
+ (%25s)', args.language, langs%5Bargs.language%5D%5B'description'%5D
 )%0A  
@@ -1430,20 +1430,20 @@
 hed_lang
-uage
+_ids
 :%0A      
@@ -1549,32 +1549,41 @@
              for
+ lang_id,
  lang in sorted(
@@ -1592,11 +1592,12 @@
 ngs.
-key
+item
 s())
@@ -1646,21 +1646,17 @@
 lang
+_id
 , lang
-s%5Blang%5D
 %5B'de
@@ -1860,24 +1860,27 @@
     for lang
+_id
  in sorted(m
@@ -1890,20 +1890,20 @@
 hed_lang
-uage
+_ids
 ):%0A     
@@ -1929,23 +1929,62 @@
 emit('%25s
+ (%25s)
 ', lang
+_id, langs%5Blang_id%5D%5B'description'%5D
 )%0A      
@@ -3240,14 +3240,18 @@
 def 
-search
+get_ids_of
 _mat
@@ -3263,16 +3263,17 @@
 language
+s
 (languag
@@ -3415,20 +3415,20 @@
 hed_lang
-uage
+_ids
  = %5B%5D%0A  
@@ -3432,16 +3432,25 @@
 %0A    for
+ lang_id,
  support
@@ -3478,13 +3478,12 @@
 ict.
-value
+item
 s():
@@ -3581,20 +3581,20 @@
 lang
-uage
+_ids
 .append(
 supp
@@ -3593,37 +3593,15 @@
 end(
-supported_lang%5B'description'%5D
+lang_id
 )%0A  
@@ -3617,17 +3617,17 @@
 matched_lang
-uage
+_ids
 %0A

fix a confusion between language-id and language-description