#!/usr/bin/env python3
# Copyright (C) 2021 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.
"""Generates TypeScript files that import all subdirectories and
registers them with plugin registry. If you have three modules:
- core/
- plugins/foo_plugin/
- plugins/bar_plugin/
In general you would like the dependency to only go one way:
- plugins/foo_plugin/ -> core/
We want to avoid manually editing core/ for every plugin.

This generates code like:

import {pluginRegistry} from '../common/plugins';

import {plugin as fooPlugin} from '../plugins/foo_plugin';
import {plugin as barPlugin} from '../plugins/bar_plugin';

pluginRegistry.register(fooPlugin);
pluginRegistry.register(barPlugin);
"""

from __future__ import print_function

import os
import argparse
import subprocess
import sys

ROOT_DIR = os.path.dirname(os.path.dirname(os.path.realpath(__file__)))
UI_SRC_DIR = os.path.join(ROOT_DIR, 'ui', 'src')
PLUGINS_PATH = os.path.join(UI_SRC_DIR, 'common', 'plugins')


def to_camel_case(s):
  first, *rest = s.split('_')
  return first + ''.join(x.title() for x in rest)


def gen_imports(input_dir, output_path):
  paths = [os.path.join(input_dir, p) for p in os.listdir(input_dir)]
  paths = [p for p in paths if os.path.isdir(p)]
  paths.sort()

  output_dir = os.path.dirname(output_path)
  rel_plugins_path = os.path.relpath(PLUGINS_PATH, output_dir)

  imports = []
  registrations = []
  for path in paths:
    rel_path = os.path.relpath(path, output_dir)
    snake_name = os.path.basename(path)
    camel_name = to_camel_case(snake_name)
    imports.append(f"import {{plugin as {camel_name}}} from '{rel_path}';")
    registrations.append(f"pluginRegistry.register({camel_name});")

  header = f"import {{pluginRegistry}} from '{rel_plugins_path}';"
  import_text = '\n'.join(imports)
  registration_text = '\n'.join(registrations)

  expected = f"{header}\n\n{import_text}\n\n{registration_text}"

  with open(output_path, 'w') as f:
    f.write(expected)
  return True


def main():
  parser = argparse.ArgumentParser(
      description=__doc__, formatter_class=argparse.RawDescriptionHelpFormatter)
  parser.add_argument('INPUT')
  parser.add_argument('--out', required=True)
  args = parser.parse_args()
  input_dir = args.INPUT
  output_path = args.out

  if not os.path.isdir(input_dir):
    print(f'INPUT argument {input_dir} must be a directory')
    exit(1)

  output_dir = os.path.dirname(output_path)
  if output_dir and not os.path.isdir(output_dir):
    print(f'--out ({output_path}) parent directory ({output_dir}) must exist')
    exit(1)
  if os.path.isdir(output_path):
    print(f'--out ({output_path}) should not be a directory')
    exit(1)

  success = gen_imports(input_dir, output_path)
  return 0 if success else 1


if __name__ == '__main__':
  exit(main())
