apply plugin: "cpp"
apply plugin: "com.google.protobuf"

description = 'The protoc plugin for gRPC Java'

buildscript {
    repositories {
        mavenCentral()
        mavenLocal()
    }
    dependencies {
        classpath libraries.protobuf_plugin
    }
}

def artifactStagingPath = "$buildDir/artifacts" as File
// Adds space-delimited arguments from the environment variable env to the
// argList.
def addEnvArgs = { env, argList ->
  def value = System.getenv(env)
  if (value != null) {
    value.split(' +').each() { it -> argList.add(it) }
  }
}

// Adds corresponding "-l" option to the argList if libName is not found in
// LDFLAGS. This is only used for Mac because when building for uploadArchives
// artifacts, we add the ".a" files directly to LDFLAGS and without "-l" in
// order to get statically linked, otherwise we add the libraries through "-l"
// so that they can be searched for in default search paths.
def addLibraryIfNotLinked = { libName, argList ->
  def ldflags = System.env.LDFLAGS
  if (ldflags == null || !ldflags.contains('lib' + libName + '.a')) {
    argList.add('-l' + libName)
  }
}

def String arch = rootProject.hasProperty('targetArch') ? rootProject.targetArch : osdetector.arch
def boolean vcDisable = rootProject.hasProperty('vcDisable') ? rootProject.vcDisable : false

model {
  toolChains {
    // If you have both VC and Gcc installed, VC will be selected, unless you
    // set 'vcDisable=true'
    if (!vcDisable) {
      visualCpp(VisualCpp) {
      }
    }
    gcc(Gcc) {
    }
    clang(Clang) {
    }
  }

  platforms {
    x86_32 {
      architecture "x86"
    }
    x86_64 {
      architecture "x86_64"
    }
  }

  components {
    java_plugin(NativeExecutableSpec) {
      if (arch in ['x86_32', 'x86_64']) {
        // If arch is not within the defined platforms, we do not specify the
        // targetPlatform so that Gradle will choose what is appropriate.
        targetPlatform arch
      }
      baseName "$protocPluginBaseName"
    }
  }
}

configurations {
  testNanoCompile
}

dependencies {
  testCompile project(':grpc-protobuf'),
              project(':grpc-stub')
  testNanoCompile project(':grpc-protobuf-nano'),
                  project(':grpc-stub')
}

sourceSets {
  testNano {
    proto {
      setSrcDirs(['src/test/proto'])
    }
  }
}

protobuf {
  protoc {
    if (project.hasProperty('protoc')) {
      path = project.protoc
    } else {
      artifact = "com.google.protobuf:protoc:${protobufVersion}"
    }
  }
  plugins {
    grpc {
      path = javaPluginPath
    }
  }
  generateProtoTasks {
    all()*.dependsOn 'java_pluginExecutable'
    ofSourceSet('test')*.plugins {
      grpc {}
    }
    ofSourceSet('testNano').each { task ->
      task.builtins {
        remove java
        javanano {
          option 'ignore_services=true'
        }
      }
      task.plugins {
        grpc {
          option 'nano=true'
        }
      }
    }
  }
}

checkstyleTestNano {
  source = fileTree(dir: "src/testNano", include: "**/*.java")
}

println "*** Building codegen requires Protobuf version ${protobufVersion}"
println "*** Please refer to https://github.com/grpc/grpc-java/blob/master/COMPILING.md#how-to-build-code-generation-plugin"

binaries.all {
  if (toolChain in Gcc || toolChain in Clang) {
    cppCompiler.args "--std=c++0x"
    addEnvArgs("CXXFLAGS", cppCompiler.args)
    addEnvArgs("CPPFLAGS", cppCompiler.args)
    if (osdetector.os == "osx") {
      cppCompiler.args "-mmacosx-version-min=10.7", "-stdlib=libc++"
      addLibraryIfNotLinked('protoc', linker.args)
      addLibraryIfNotLinked('protobuf', linker.args)
    } else if (osdetector.os == "windows") {
      linker.args "-static", "-lprotoc", "-lprotobuf", "-static-libgcc", "-static-libstdc++", "-s"
    } else {
      // Link protoc, protobuf, libgcc and libstdc++ statically.
      // Link other (system) libraries dynamically.
      // Clang under OSX doesn't support these options.
      linker.args "-Wl,-Bstatic", "-lprotoc", "-lprotobuf", "-static-libgcc", "-static-libstdc++",
                  "-Wl,-Bdynamic", "-lpthread", "-s"
    }
    addEnvArgs("LDFLAGS", linker.args)
  } else if (toolChain in VisualCpp) {
    cppCompiler.args "/EHsc", "/MT"
    if (rootProject.hasProperty('vcProtobufInclude')) {
      cppCompiler.args "/I${rootProject.vcProtobufInclude}"
    }
    linker.args "libprotobuf.lib", "libprotoc.lib"
    if (rootProject.hasProperty('vcProtobufLibs')) {
      linker.args "/LIBPATH:${rootProject.vcProtobufLibs}"
    }
  }
}

task buildArtifacts(type: Copy) {
  dependsOn 'java_pluginExecutable'
  from("$buildDir/binaries") {
    if (osdetector.os != 'windows') {
      rename 'protoc-gen-grpc-java', '$0.exe'
    }
  }
  into artifactStagingPath
}

archivesBaseName = "$protocPluginBaseName"

artifacts {
  archives("$artifactStagingPath/java_pluginExecutable/${protocPluginBaseName}.exe" as File) {
    classifier osdetector.os + "-" + arch
    type "exe"
    extension "exe"
    builtBy buildArtifacts
  }
}

// Exe files are skipped by Maven by default. Override it.
// Also skip jar files that is generated by the java plugin.
[
  install.repositories.mavenInstaller,
  uploadArchives.repositories.mavenDeployer,
]*.addFilter('all') {artifact, file ->
  ! (file.getName().endsWith('jar') || file.getName().endsWith('jar.asc'))
}

[
  uploadArchives.repositories.mavenDeployer,
]*.beforeDeployment {
  def ret = exec {
    executable 'bash'
    args 'check-artifact.sh', osdetector.os, arch
  }
  if (ret.exitValue != 0) {
    throw new GradleException("check-artifact.sh exited with " + ret.exitValue)
  }
}

test.dependsOn('testGolden', 'testNanoGolden')

def configureTestTask(Task task, String suffix) {
  task.dependsOn "generateTest${suffix}Proto"
  if (osdetector.os != 'windows') {
    task.executable "diff"
  } else {
    task.executable "fc"
  }
  // File isn't found on Windows if last slash is forward-slash
  def slash = System.getProperty("file.separator")
  task.args "$buildDir/generated/source/proto/test${suffix}/grpc/io/grpc/testing/integration${slash}TestServiceGrpc.java",
       "$projectDir/src/test/golden/TestService${suffix}.java.txt"
}

task testGolden(type: Exec)
task testNanoGolden(type: Exec)
configureTestTask(testGolden, '')
configureTestTask(testNanoGolden, 'Nano')
