#!/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 {plugin as fooPlugin} from '../plugins/foo_plugin';
import {plugin as barPlugin} from '../plugins/bar_plugin';

export default [
  fooPlugin,
  barPlugin,
];
"""

from __future__ import print_function

import os
import argparse
import re

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):
  # Split string on periods and underscores
  first, *rest = re.split(r'\.|\_', s)
  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(camel_name)

  import_text = '\n'.join(imports)
  registration_text = 'export default [\n'
  for camel_name in registrations:
    registration_text += f"  {camel_name},\n"
  registration_text += '];\n'

  expected = f"{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())
