# Copyright 2019 - The Android Open Source Project
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

###############################################################################
# This script adds a HTML snippet to the generated reference docs located at
# developer.android.com/reference.  The snippet renders HTML that adds links to
# toggle between the Java and Kotlin versions of the page.
###############################################################################

import getopt
import os
import sys


# GLOBAL FLAGS

global stubs
global java_stubs, kotlin_stubs
global work, verbose, show_solo, max_stubs
global java_source_abs_path
global kotlin_source_abs_path

verbose = False  # set True to list all files as they are stubbed (--verbose)
work = False  # set True to insert stubs, False to do a dry run for stats (--work)
show_solo = False  # set True to list files that only appear in one language, rather than both (--solo)
max_stubs = 0  # set positive to create a limited number of stubs (--max 12)


# You must run the script from the refodcs reference/ root directory

java_ref_root = os.getcwd()
kotlin_ref_root = os.path.join(java_ref_root, "kotlin")
root = os.path.split(java_ref_root)[1]
if root != "reference":
  print("You must cd to the refocs reference/ root directory")
  sys.exit()


# This method inserts the language switcher into the two top-level Android
# Platform pages: packages.html and classes.html
# For both Java and Kotlin
def insert_platform_summaries():
  global stubs
  global java_stubs, kotlin_stubs
  global verbose, work, show_solo
  global java_source_abs_path
  global kotlin_source_abs_path

  stubs = 0
  java_stubs = 0
  kotlin_stubs = 0

  java_source_abs_path = java_ref_root
  kotlin_source_abs_path = kotlin_ref_root
  insert_stub(os.path.join(java_ref_root, "packages.html"), True, True)
  insert_stub(os.path.join(kotlin_ref_root, "packages.html"), False, True)

  insert_stub(os.path.join(java_ref_root, "classes.html"), True, True)
  insert_stub(os.path.join(kotlin_ref_root, "classes.html"), False, True)

# This method uses switcher2, which assumes the refdocs stay in their current
# assymetrical dirs (ref/android and ref/kotlin/android)
# And just puts the switcher in the existing docs
def insert_stub(doc, java, both):
  global stubs
  global java_stubs, kotlin_stubs
  global verbose, work, show_solo
  global java_source_abs_path
  global kotlin_source_abs_path

  stubs = stubs+1

  if verbose:
    print("File: ", stubs, doc)
  else:
    fn  = os.path.split(doc)
    print("File: ", stubs, fn[1], end="\r")

  if (java):
    java_stubs = java_stubs + 1
  else:
    kotlin_stubs = kotlin_stubs + 1

  if (work):
    with open(doc, "r") as f:
      file_content = f.read()

    if (java):
      file_path = doc[len(java_ref_root) + 1 :]
      if (both):
        file_content = file_content.replace(
            "</h1>",
            "</h1>\n{% setvar page_path %}_page_path_{% endsetvar %}\n{% setvar"
            " can_switch %}1{% endsetvar %}\n{% include"
            ' "reference/_java_switcher2.md" %}',
        )
        file_content = file_content.replace("_page_path_", file_path)
      else:
        file_content = file_content.replace(
            "</h1>", '</h1>\n{% include "reference/_java_switcher2.md" %}'
        )
    else:
      file_path = doc[len(kotlin_ref_root) + 1 :]
      if (both):
        file_content = file_content.replace(
            "</h1>",
            "</h1>\n{% setvar page_path %}_page_path_{% endsetvar %}\n{% setvar"
            " can_switch %}1{% endsetvar %}\n{% include"
            ' "reference/_kotlin_switcher2.md" %}',
        )
        file_content = file_content.replace("_page_path_", file_path)
      else:
        file_content = file_content.replace(
            "</h1>", '</h1>\n{% include "reference/_kotlin_switcher2.md" %}'
        )

    with open(doc, "w") as f:
      f.write(file_content)
    os.chmod(doc, 0o644)


def scan_files(stem):
  global work, verbose, show_solo, max_stubs
  global stubs
  global java_stubs, kotlin_stubs
  global java_source_abs_path
  global kotlin_source_abs_path

  java_source_abs_path = os.path.join(java_ref_root, stem)
  kotlin_source_abs_path = os.path.join(kotlin_ref_root, stem)

  # Pass 1
  # Loop over java content, create stubs for java,
  # and for corresponding Kotlin (when it exsits)

  # solo is java-only classes
  # both is java+kotlin
  stubs = 0
  java_stubs = 0
  kotlin_stubs = 0
  solo = 0
  both = 0

  print("*** PASS1 (Java) ***")
  maxed_out = False
  for root, dirs, files in os.walk(java_source_abs_path):
      if maxed_out:
        break;
      for file_ in files:
        ext = os.path.splitext(file_)
        ext = ext[1]
        if not ext:
          # this catches package-lists with no extension
          print("***", os.path.join(root, file_))
        elif ext != ".html":
          # filter out png, yaml, etc
          continue
        else:
          # we have java content
          doc = os.path.join(root, file_)



          # look for matching kotlin file
          kotlinsource = doc.replace(java_source_abs_path, kotlin_source_abs_path)
          if os.path.isfile(kotlinsource):
             # corresponding kotlin content exists
             insert_stub(doc, True, True)
             insert_stub(kotlinsource, False, True)
             both = both+1
          else:
            # no kotlin content
            if (show_solo):
              print("solo: ", doc)
            insert_stub(doc, True, False)
            solo = solo+1

          if max_stubs>0 and stubs>=max_stubs:
            print()
            print("max java stubs: ", max_stubs)
            maxed_out = True;
            break

  print("Java+Kotlin:", both, "Only Java:", solo)
  print()


  # PASS 2
  # Loop over kotlin content, create stubs for Kotlin-only APIs
  print("*** PASS2 (Kotlin) ***")
  solo = 0
  both = 0
  maxed_out = False
  stubs = 0
  for root, dirs, files in os.walk(kotlin_source_abs_path):
      if maxed_out:
        break;
      for file_ in files:
        ext = os.path.splitext (file_)
        ext = ext[1]
        if not ext:
          # this catches package-lists with no extension
          print("***", os.path.join(root, file_))
        elif ext != ".html":
          # filter out png, yaml, etc
          continue
        else:
          # we have kotlin content
          doc = os.path.join(root, file_)
          javadoc = doc.replace(kotlin_source_abs_path, java_source_abs_path)
          file_name = os.path.splitext(file_)[0]
          file_path = doc[len(kotlin_source_abs_path)+1:]
          include_path = os.path.join("/reference/_kotlin", file_path)

          if os.path.isfile(javadoc):
             # corresponding java content exists
             # so we already created the kotlin stub file
             # nothing to do
             both = both+1
          else:
            # no java content
            # create the kotlin stub file
            if (show_solo):
              print("solo: ", doc)
            insert_stub(doc , False, False)
            solo = solo+1

          if (max_stubs>0 and stubs>=max_stubs):
            print()
            print("max koltin stubs: ", max_stubs)
            maxed_out = True;
            break


  print("Java+Kotlin:", both, "Only Kotlin:", solo)
  print()
  print("Java: ", java_stubs, " Kotlin: ", kotlin_stubs, "Total: ", java_stubs + kotlin_stubs)


def main(argv):

  global work, verbose, show_solo, max_stubs
  global java_source_abs_path
  global kotlin_source_abs_path
  stem = ""

  try:
    opts, args = getopt.getopt(argv,"",["work","verbose","solo","max="])
  except getopt.GetoptError:
    print('USAGE: switcher --work --verbose --solo --max=<max_stubs> platform|androidx|support|chrome')
    sys.exit(2)

  for opt, arg in opts:
    if opt == '--work':
       work = True
    elif opt == "--verbose":
       print("verbose")
       verbose = True
    elif opt == "--solo":
       print("verbose")
       show_solo = True
    elif opt == "--max":
       max_stubs = int(arg)
       print("max ", max_stubs)

  if len(args)>0:
    source = args[0]
    if source == "platform":
      stem = "android"
      print()
      print("*** PLATFORM PAGES ***")
      print("======================")

      # Insert the switchers at the top level first
      insert_platform_summaries()

    elif source == "androidx":
      stem = "androidx"
      print()
      print("*** ANDROIDX SUPPORT LIBRARY PAGES ***")
      print("======================================")

    elif source == "support":
      stem = "android/support/v4/media"
      print()
      print("*** ANDROIDX SUPPORT LIBRARY PAGES ***")
      print("======================================")

    elif source == "chrome":
      stem = "org/chromium/support_lib_boundary"
      print()
      print("*** ANDROIDX CHROMIUM PAGES ***")
      print("===============================")

  if (len(stem)>0):
    scan_files(stem)
    print(" *** DONE ***")
  else:
      print('You must specify one of: platform|androidx|support|chrome')



if __name__ == "__main__":
   main(sys.argv[1:])

