# Copyright 2018 The Fuchsia Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
"""Recipe for downloading and packaging fonts."""

from collections import namedtuple

DEPS = [
    'fuchsia/git',
    'fuchsia/upload',
    'recipe_engine/cipd',
    'recipe_engine/context',
    'recipe_engine/file',
    'recipe_engine/path',
    'recipe_engine/step',
]

Repository = namedtuple('Repository', ['url', 'ref', 'fonts'])
Font = namedtuple('Font', ['name', 'path', 'files', 'license'])

REPOSITORIES = [
    Repository(
        url='https://github.com/google/fonts',
        ref='94dff3eaa9301b6640cccc63c56d6ff33d82882c',
        fonts=[
            Font(
                name='roboto',
                path=('apache', 'roboto'),
                files=[
                    'Roboto-BlackItalic.ttf',
                    'Roboto-Black.ttf',
                    'Roboto-BoldItalic.ttf',
                    'Roboto-Bold.ttf',
                    'Roboto-Italic.ttf',
                    'Roboto-LightItalic.ttf',
                    'Roboto-Light.ttf',
                    'Roboto-MediumItalic.ttf',
                    'Roboto-Medium.ttf',
                    'Roboto-Regular.ttf',
                    'Roboto-ThinItalic.ttf',
                    'Roboto-Thin.ttf',
                ],
                license=('apache', 'roboto', 'LICENSE.txt'),
            ),
            Font(
                name='robotocondensed',
                path=('apache', 'robotocondensed'),
                files=[
                    'RobotoCondensed-BoldItalic.ttf',
                    'RobotoCondensed-Bold.ttf',
                    'RobotoCondensed-Italic.ttf',
                    'RobotoCondensed-LightItalic.ttf',
                    'RobotoCondensed-Light.ttf',
                    'RobotoCondensed-Regular.ttf',
                ],
                license=('apache', 'robotocondensed', 'LICENSE.txt'),
            ),
            Font(
                name='robotomono',
                path=('apache', 'robotomono'),
                files=[
                    'RobotoMono-BoldItalic.ttf',
                    'RobotoMono-Bold.ttf',
                    'RobotoMono-Italic.ttf',
                    'RobotoMono-LightItalic.ttf',
                    'RobotoMono-Light.ttf',
                    'RobotoMono-MediumItalic.ttf',
                    'RobotoMono-Medium.ttf',
                    'RobotoMono-Regular.ttf',
                    'RobotoMono-ThinItalic.ttf',
                    'RobotoMono-Thin.ttf',
                ],
                license=('apache', 'robotomono', 'LICENSE.txt'),
            ),
            Font(
                name='robotoslab',
                path=('apache', 'robotoslab'),
                files=[
                    'RobotoSlab-Bold.ttf',
                    'RobotoSlab-Light.ttf',
                    'RobotoSlab-Regular.ttf',
                    'RobotoSlab-Thin.ttf',
                ],
                license=('apache', 'robotoslab', 'LICENSE.txt'),
            ),
        ],
    ),
    Repository(
        url='https://github.com/google/material-design-icons',
        ref='224895a86501195e7a7ff3dde18e39f00b8e3d5a',
        fonts=[
            Font(
                name='material',
                path=('iconfont',),
                files=['MaterialIcons-Regular.ttf'],
                license=('LICENSE',),
            ),
        ],
    ),
    Repository(
        url='https://github.com/googlei18n/noto-cjk',
        ref='9326451d9b4f32ec7f8640581c5053cc192039f2',
        fonts=[
            Font(
                name='noto-cjk',
                path=(),
                files=[
                    'NotoSansCJK-Black.ttc',
                    'NotoSansCJK-Bold.ttc',
                    'NotoSansCJK-DemiLight.ttc',
                    'NotoSansCJK-Light.ttc',
                    'NotoSansCJK-Medium.ttc',
                    'NotoSansCJK-Regular.ttc',
                    'NotoSansCJK-Thin.ttc',
                    'NotoSerifCJK-Black.ttc',
                    'NotoSerifCJK-Bold.ttc',
                    'NotoSerifCJK-ExtraLight.ttc',
                    'NotoSerifCJK-Light.ttc',
                    'NotoSerifCJK-Medium.ttc',
                    'NotoSerifCJK-Regular.ttc',
                    'NotoSerifCJK-SemiBold.ttc',
                ],
                license=('LICENSE',),
            ),
        ],
    ),
]


def RunSteps(api):
  cipd_pkg_dir = api.path['start_dir'].join('fonts')
  api.file.ensure_directory('makedirs', cipd_pkg_dir)

  git_repositories = []

  for repository in REPOSITORIES:
    repository_name = repository.url.rsplit('/', 1)[-1]
    with api.step.nest(repository_name):
      src_dir = api.path['start_dir'].join('src', repository_name)
      git_sha = api.git.checkout(repository.url, src_dir, ref=repository.ref)
      git_repositories.append((repository.url, git_sha))

      for font in repository.fonts:
        with api.step.nest(font.name):
          pkg_dir = cipd_pkg_dir.join(font.name)
          api.file.ensure_directory('make %s dir' % font.name, pkg_dir)

          for filename in font.files:
            path = list(font.path) + [filename]
            api.file.copy(filename, src_dir.join(*path), pkg_dir)
          api.file.copy(font.license[-1], src_dir.join(*font.license), pkg_dir)

  git_repositories.sort()
  git_repository = ','.join(r for r, _ in git_repositories)
  git_revision = ','.join(r for _, r in git_repositories)
  api.upload.cipd_package(
      'fuchsia/third_party/fonts',
      cipd_pkg_dir, [api.upload.DirectoryPath(cipd_pkg_dir)],
      {'git_revision': git_revision},
      repository=git_repository)


def GenTests(api):
  cipd_pkg_name = 'fuchsia/third_party/fonts'
  yield (api.test('existing') + api.step_data(
      'cipd.cipd search ' + cipd_pkg_name +
      ' git_revision:deadbeef,deadbeef,deadbeef',
      api.cipd.example_search(cipd_pkg_name, [])))
  yield (api.test('new'))
