# Copyright 2015 Google Inc. 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 sys
import tarfile

from tools.build_defs.docker 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_string(
    'metadata', None,
    'The JSON metadata file for this image, mandatory.')
gflags.MarkFlagAsRequired('metadata')

gflags.DEFINE_string(
    'layer', None,
    'The tar file for the top layer of this image, mandatory.')
gflags.MarkFlagAsRequired('metadata')

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

gflags.DEFINE_string(
    'base', None,
    'The 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.')

FLAGS = gflags.FLAGS


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


def create_image(output, identifier,
                 base=None, layer=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 of the top layer for this image.
    base: a base layer (optional) to merge to current layer.
    layer: the layer content (a tar file).
    metadata: the json metadata file for the top layer.
    name: symbolic name for this docker image.
    repository: repository name for this docker image.
  """
  tar = archive.TarFileWriter(output)
  # Write our id to 'top' as we are now the topmost layer.
  tar.add_file('top', content=identifier)
  # 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(identifier + '/', tarfile.DIRTYPE)
  # VERSION generally seems to contain 1.0, not entirely sure
  # what the point of this is.
  tar.add_file(identifier + '/VERSION', content=DATA_FORMAT_VERSION)
  # Add the layer file
  tar.add_file(identifier + '/layer.tar', file_content=layer)
  # Now the json metadata
  tar.add_file(identifier + '/json', file_content=metadata)
  # Merge the base if any
  if base:
    tar.add_tar(base, name_filter=_base_name_filter)
  # 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),
        '  }',
        '}']))


# Main program to create a docker image. It expect to be run with:
# create_image --output=output_file \
#              --id=@identifier \
#              [--base=base] \
#              --layer=layer.tar \
#              --metadata=metadata.json \
#              --name=myname --repository=repositoryName
# See the gflags declaration about the flags argument details.
def main(unused_argv):
  identifier = FLAGS.id
  if identifier.startswith('@'):
    with open(identifier[1:], 'r') as f:
      identifier = f.read()
  create_image(FLAGS.output, identifier, FLAGS.base,
               FLAGS.layer, FLAGS.metadata,
               FLAGS.name, FLAGS.repository)

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