# GRPC CocoaPods podspec
# This file has been automatically generated from a template file.
# Please look at the templates directory instead.
# This file can be regenerated from the template by running
# tools/buildgen/generate_projects.sh

# Copyright 2015, Google Inc.
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met:
#
#     * Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
#     * Redistributions in binary form must reproduce the above
# copyright notice, this list of conditions and the following disclaimer
# in the documentation and/or other materials provided with the
# distribution.
#     * Neither the name of Google Inc. nor the names of its
# contributors may be used to endorse or promote products derived from
# this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

<%!
bad_header_names = ('time.h', 'string.h')
def fix_header_name(name):
  split_name = name.split('/')
  if split_name[-1] in bad_header_names:
    split_name[-1] = 'grpc_' + split_name[-1]
  if split_name[0] == 'include':
    split_name = split_name[1:]
  return '/'.join(split_name)

def grpc_files(libs):
  out = []
  for lib in libs:
    if lib.name in ("grpc", "gpr"):
      out.extend(fix_header_name(h) for h in lib.get('headers', []))
      out.extend(fix_header_name(h) for h in lib.get('public_headers', []))
      out.extend(lib.get('src', []))
  return out;

def grpc_private_headers(libs):
  out = []
  for lib in libs:
    if lib.name in ("grpc", "gpr"):
      out.extend(lib.get('headers', []))
  return out
%>
Pod::Spec.new do |s|
  s.name     = 'gRPC'
  s.version  = '0.7.0'
  s.summary  = 'gRPC client library for iOS/OSX'
  s.homepage = 'http://www.grpc.io'
  s.license  = 'New BSD'
  s.authors  = { 'The gRPC contributors' => 'grpc-packages@google.com' }

  # s.source = { :git => 'https://github.com/grpc/grpc.git',
  #              :tag => 'release-0_10_0-objectivec-0.6.0' }

  s.ios.deployment_target = '6.0'
  s.osx.deployment_target = '10.8'
  s.requires_arc = true

  objc_dir = 'src/objective-c'

  # Reactive Extensions library for iOS.
  s.subspec 'RxLibrary' do |ss|
    src_dir = "#{objc_dir}/RxLibrary"
    ss.source_files = "#{src_dir}/*.{h,m}", "#{src_dir}/**/*.{h,m}"
    ss.private_header_files = "#{src_dir}/private/*.h"
    ss.header_mappings_dir = "#{objc_dir}"
  end

  # Core cross-platform gRPC library, written in C.
  s.subspec 'C-Core' do |ss|
    ss.source_files = ${(',\n' + 22*' ').join('\'%s\'' % f for f in grpc_files(libs))}

    ss.private_header_files = ${(',\n' + 30*' ').join('\'%s\'' % f for f in grpc_private_headers(libs))}

    ss.header_mappings_dir = '.'

    ss.requires_arc = false
    ss.libraries = 'z'
    ss.dependency 'OpenSSL', '~> 1.0.200'

    # ss.compiler_flags = '-GCC_WARN_INHIBIT_ALL_WARNINGS', '-w'
  end

  # This is a workaround for Cocoapods Issue #1437.
  # It renames time.h and string.h to grpc_time.h and grpc_string.h.
  # It needs to be here (top-level) instead of in the C-Core subspec because Cocoapods doesn't run
  # prepare_command's of subspecs.
  #
  # TODO(jcanizales): Try out others' solutions at Issue #1437.
  s.prepare_command = <<-CMD
    # Move contents of include up a level to avoid manually specifying include paths
    cp -r "include/grpc" "."

    DIR_TIME="grpc/support"
    BAD_TIME="$DIR_TIME/time.h"
    GOOD_TIME="$DIR_TIME/grpc_time.h"
    grep -rl "$BAD_TIME" grpc src/core src/objective-c/GRPCClient | xargs sed -i '' -e s@$BAD_TIME@$GOOD_TIME@g
    if [ -f "$BAD_TIME" ];
    then
      mv -f "$BAD_TIME" "$GOOD_TIME"
    fi

    DIR_STRING="src/core/support"
    BAD_STRING="$DIR_STRING/string.h"
    GOOD_STRING="$DIR_STRING/grpc_string.h"
    grep -rl "$BAD_STRING" grpc src/core src/objective-c/GRPCClient | xargs sed -i '' -e s@$BAD_STRING@$GOOD_STRING@g
    if [ -f "$BAD_STRING" ];
    then
      mv -f "$BAD_STRING" "$GOOD_STRING"
    fi
  CMD

  # Objective-C wrapper around the core gRPC library.
  s.subspec 'GRPCClient' do |ss|
    src_dir = "#{objc_dir}/GRPCClient"
    ss.source_files = "#{src_dir}/*.{h,m}", "#{src_dir}/**/*.{h,m}"
    ss.private_header_files = "#{src_dir}/private/*.h"
    ss.header_mappings_dir = "#{objc_dir}"

    ss.dependency 'gRPC/C-Core'
    ss.dependency 'gRPC/RxLibrary'

    # Certificates, to be able to establish TLS connections:
    ss.resource_bundles = { 'gRPCCertificates' => ['etc/roots.pem'] }
  end

  # RPC library for ProtocolBuffers, based on gRPC
  s.subspec 'ProtoRPC' do |ss|
    src_dir = "#{objc_dir}/ProtoRPC"
    ss.source_files = "#{src_dir}/*.{h,m}"
    ss.header_mappings_dir = "#{objc_dir}"

    ss.dependency 'gRPC/GRPCClient'
    ss.dependency 'gRPC/RxLibrary'
    ss.dependency 'Protobuf', '~> 3.0.0-alpha-3'
  end
end
