#!/usr/bin/env python

from lxml import etree
import os
import re
import subprocess
import sys

fuchsia_dir = os.environ['FUCHSIA_DIR']
idea_dir = os.path.join(fuchsia_dir, '.idea')


def find_dart_directories():
  # Ask GN for all labels that depends on the target Dart SDK.
  refs = subprocess.check_output([
      os.path.join(fuchsia_dir, 'packages', 'gn',
                   'gn.py'), 'refs', os.environ['FUCHSIA_BUILD_DIR'],
      '//dart:create_sdk(//build/toolchain:host_x64)'
  ])
  # Turn that into a set of unique directories for the labels.
  label_dirs = {
      os.path.join(fuchsia_dir, re.sub(r':.*', '', label[2:]))
      for label in refs.split('\n') if len(label)
  }
  # Filter to just the ones that contain dart code.
  dart_dirs = [
      d for d in label_dirs if os.path.exists(os.path.join(d, 'pubspec.yaml'))
  ]
  # Sort them by the leaf name. This how IntelliJ seems to sort them.
  dart_dirs.sort(key=lambda d: os.path.basename(d))

  return dart_dirs


def write_dart_iml(dart_dir):
  # TODO(ianloic): check if it already exists?
  # TODO(ianloic): handle tests specially
  relative_dart_dir = os.path.relpath(dart_dir, fuchsia_dir)
  iml_file = os.path.join(idea_dir, 'modules', relative_dart_dir) + '.iml'
  iml_dir = os.path.dirname(iml_file)
  if not os.path.exists(iml_dir):
    os.makedirs(iml_dir)
  relative_source_dir = os.path.relpath(dart_dir, iml_dir)
  module = etree.Element('module', type='WEB_MODULE', version='4')
  component = etree.SubElement(module, 'component', name='NewModuleRootManager')
  component.set('inherit-compiler-output', 'true')
  etree.SubElement(component, 'exclude-output')
  etree.SubElement(
      component, 'content', url='file://$MODULE_DIR$/' + relative_source_dir)
  etree.SubElement(component, 'orderEntry', type='inheritedJdk')
  etree.SubElement(
      component, 'orderEntry', type='sourceFolder', forTests='false')

  with open(iml_file, 'w') as f:
    f.write(
        etree.tostring(
            module, encoding='UTF-8', xml_declaration=True, pretty_print=True))

  return iml_file


def write_dart_modules(dart_dirs):
  # TODO(ianloic): merge with existing file?
  project = etree.Element('project', version='4')
  component = etree.SubElement(
      project, 'component', name='ProjectModuleManager')
  modules = etree.SubElement(component, 'modules')
  for dart_dir in dart_dirs:
    iml_file = write_dart_iml(dart_dir)
    relative_dart_dir = os.path.relpath(dart_dir, fuchsia_dir)
    relative_iml_file = os.path.relpath(iml_file, fuchsia_dir)
    etree.SubElement(
        modules,
        'module',
        fileurl='file://$PROJECT_DIR$/' + relative_iml_file,
        filepath='$PROJECT_DIR$/' + relative_iml_file,
        group=os.path.dirname(relative_dart_dir))

  with open(os.path.join(idea_dir, 'modules.xml'), 'w') as f:
    f.write(
        etree.tostring(
            project, encoding='UTF-8', xml_declaration=True, pretty_print=True))


def write_basic_project_files():
  # Make the .idea directory if needed.
  if not os.path.exists(idea_dir):
    os.makedirs(idea_dir)

  # Create skeleton misc.xml and workspace.xml.
  skeleton = etree.tostring(
      etree.Element('project', version='4'),
      encoding='UTF-8',
      xml_declaration=True,
      pretty_print=True)
  for fn in ('misc.xml', 'workspace.xml'):
    path = os.path.join(idea_dir, fn)
    if not os.path.exists(path):
      with open(path, 'w') as f:
        f.write(skeleton)


if __name__ == '__main__':
  dart_dirs = find_dart_directories()
  write_basic_project_files()
  write_dart_modules(dart_dirs)
