# Copyright 2015 The Bazel Authors. All rights reserved.
#
# 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 tool creates a docker image from a layer and the various metadata."""

import json
import re
import sys
import tarfile

from tools.build_defs.docker import utils
from tools.build_defs.pkg import archive
from third_party.py import gflags

# Hardcoded docker versions that we are claiming to be.
DATA_FORMAT_VERSION = '1.0'

gflags.DEFINE_string(
    'output', None,
    'The output file, mandatory')
gflags.MarkFlagAsRequired('output')

gflags.DEFINE_multistring(
    'layer', [],
    'Layer tar files and their identifiers that make up this image')

gflags.DEFINE_string(
    'id', None,
    'The hex identifier of this image (hexstring or @filename), mandatory.')
gflags.MarkFlagAsRequired('id')

gflags.DEFINE_string('config', None,
                     'The JSON configuration file for this image, mandatory.')
gflags.MarkFlagAsRequired('config')

gflags.DEFINE_string('base', None, 'The base image file for this image.')

gflags.DEFINE_string(
    'legacy_id', None,
    'The legacy hex identifier of this layer (hexstring or @filename).')

gflags.DEFINE_string('metadata', None,
                     'The legacy JSON metadata file for this layer.')

gflags.DEFINE_string('legacy_base', None,
                     'The legacy base image file for this image.')

gflags.DEFINE_string(
    'repository', None,
    'The name of the repository to add this image.')

gflags.DEFINE_string(
    'name', None,
    'The symbolic name of this image.')

gflags.DEFINE_multistring('tag', None,
                          'The repository tags to apply to the image')

FLAGS = gflags.FLAGS


def _base_name_filter(name):
  """Do not add multiple times 'top' and 'repositories' when merging images."""
  filter_names = ['top', 'repositories', 'manifest.json']
  return all([not name.endswith(s) for s in filter_names])


def _create_image(tar,
                  identifier,
                  layers,
                  config,
                  tags=None,
                  base=None,
                  legacy_base=None,
                  metadata_id=None,
                  metadata=None,
                  name=None,
                  repository=None):
  """Creates a Docker image.

  Args:
    tar: archive.TarFileWriter object for the docker image file to create.
    identifier: the identifier for this image (sha256 of the metadata).
    layers: the layer content (a sha256 and a tar file).
    config: the configuration file for the image.
    tags: tags that apply to this image.
    base: a base layer (optional) to build on top of.
    legacy_base: a base layer (optional) to build on top of.
    metadata_id: the identifier of the top layer for this image.
    metadata: the json metadata file for the top layer.
    name: symbolic name for this docker image.
    repository: repository name for this docker image.
  """
  # add the image config referenced by the Config section in the manifest
  # the name can be anything but docker uses the format below
  config_file_name = identifier + '.json'
  tar.add_file(config_file_name, file_content=config)

  layer_file_names = []

  if metadata_id:
    # Write our id to 'top' as we are now the topmost layer.
    tar.add_file('top', content=metadata_id)

    # Each layer is encoded as a directory in the larger tarball of the form:
    #  {id}\
    #    layer.tar
    #    VERSION
    #    json
    # Create the directory for us to now fill in.
    tar.add_file(metadata_id + '/', tarfile.DIRTYPE)
    # VERSION generally seems to contain 1.0, not entirely sure
    # what the point of this is.
    tar.add_file(metadata_id + '/VERSION', content=DATA_FORMAT_VERSION)
    # Add the layer file
    layer_file_name = metadata_id + '/layer.tar'
    layer_file_names.append(layer_file_name)
    tar.add_file(layer_file_name, file_content=layers[0]['layer'])
    # Now the json metadata
    tar.add_file(metadata_id + '/json', file_content=metadata)

    # Merge the base if any
    if legacy_base:
      tar.add_tar(legacy_base, name_filter=_base_name_filter)
  else:
    for layer in layers:
      # layers can be called anything, so just name them by their sha256
      layer_file_name = identifier + '/' + layer['name'] + '.tar'
      layer_file_names.append(layer_file_name)
      tar.add_file(layer_file_name, file_content=layer['layer'])

  base_layer_file_names = []
  parent = None
  if base:
    latest_item = utils.GetLatestManifestFromTar(base)
    if latest_item:
      base_layer_file_names = latest_item.get('Layers', [])
      config_file = latest_item['Config']
      parent_search = re.search('^(.+)\\.json$', config_file)
      if parent_search:
        parent = parent_search.group(1)

  manifest_item = {
      'Config': config_file_name,
      'Layers': base_layer_file_names + layer_file_names,
      'RepoTags': tags or []
  }
  if parent:
    manifest_item['Parent'] = 'sha256:' + parent

  manifest = [manifest_item]

  manifest_content = json.dumps(manifest, sort_keys=True)
  tar.add_file('manifest.json', content=manifest_content)

  # In addition to N layers of the form described above, there is
  # a single file at the top of the image called repositories.
  # This file contains a JSON blob of the form:
  # {
  #   'repo':{
  #     'tag-name': 'top-most layer hex',
  #     ...
  #   },
  #   ...
  # }
  if repository:
    tar.add_file('repositories', content='\n'.join([
        '{',
        '  "%s": {' % repository,
        '    "%s": "%s"' % (name, identifier),
        '  }',
        '}']))


def create_image(output,
                 identifier,
                 layers,
                 config,
                 tags=None,
                 base=None,
                 legacy_base=None,
                 metadata_id=None,
                 metadata=None,
                 name=None,
                 repository=None):
  """Creates a Docker image.

  Args:
    output: the name of the docker image file to create.
    identifier: the identifier for this image (sha256 of the metadata).
    layers: the layer content (a sha256 and a tar file).
    config: the configuration file for the image.
    tags: tags that apply to this image.
    base: a base layer (optional) to build on top of.
    legacy_base: a base layer (optional) to build on top of.
    metadata_id: the identifier of the top layer for this image.
    metadata: the json metadata file for the top layer.
    name: symbolic name for this docker image.
    repository: repository name for this docker image.
  """
  with archive.TarFileWriter(output) as tar:
    _create_image(tar, identifier, layers, config, tags, base, legacy_base,
                  metadata_id, metadata, name, repository)


# Main program to create a docker image. It expect to be run with:
# create_image --output=output_file \
#              --id=@identifier \
#              [--base=base] \
#              --layer=@identifier=layer.tar \
#              --metadata=metadata.json \
#              --name=myname --repository=repositoryName \
#              --tag=repo/image:tag
# See the gflags declaration about the flags argument details.
def main(unused_argv):
  identifier = utils.ExtractValue(FLAGS.id)
  legacy_id = utils.ExtractValue(FLAGS.legacy_id)

  layers = []
  for kv in FLAGS.layer:
    (k, v) = kv.split('=', 1)
    layers.append({
        'name': utils.ExtractValue(k),
        'layer': v,
    })

  create_image(FLAGS.output, identifier, layers, FLAGS.config, FLAGS.tag,
               FLAGS.base, FLAGS.legacy_base, legacy_id, FLAGS.metadata,
               FLAGS.name, FLAGS.repository)

if __name__ == '__main__':
  main(FLAGS(sys.argv))
