# -*- coding: utf-8; mode: tcl; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- vim:fenc=utf-8:ft=tcl:et:sw=4:ts=4:sts=4

PortSystem          1.0
PortGroup           active_variants 1.1
PortGroup           cmake   1.1
PortGroup           github  1.0
PortGroup           legacysupport 1.1
PortGroup           qt6     1.0
PortGroup           conflicts_build 1.0

name                qgis4
categories          gis
maintainers         {i0ntempest @i0ntempest} {yahoo.com:n_larsson @nilason} openmaintainer
description         QGIS 4 is a user-friendly GIS based on Qt 6
long_description    QGIS is a full-featured, user-friendly, free-and-open-source \
                    (FOSS) geographical information system (GIS) that runs on    \
                    Unix platforms, Windows, and MacOS.

license             GPL-2+

homepage            https://www.qgis.org/

github.setup        qgis QGIS 4_2_3 final-
github.tarball_from archive
revision            0
set app_name        QGIS[lindex [split ${github.version} _] 0]

checksums           rmd160  cc083ddd852c81dd9ebe15d4da6e60956994ac7f \
                    sha256  b847e671e89c17475238680f8c66f75e30394f18714411e3b2e70c02b603c234 \
                    size    242223514

# See: https://github.com/libspatialindex/libspatialindex/issues/276
conflicts_build     spatialindex

version             [string map {_ .} ${github.version}]

# Enable use of 'macports-libcxx' for macOS 10.14 and earlier, as port uses
# libcxx features normally only available on 10.15 and later.
legacysupport.newest_darwin_requires_legacy \
                    18
legacysupport.use_mp_libcxx \
                    yes

compiler.cxx_standard \
                    2020

# QGIS 4.2 requires Qt >= 6.4 and C++20
# MP only provides 6.4+, left here for future use
#qt6.blacklist       {< 6.4}
qt6.find_method     prefix_path

depends_build-append \
                    port:bison \
                    port:flex \
                    port:nlohmann-json \
                    port:opencl-clhpp \
                    port:ld64 \
                    path:bin/pkg-config:pkgconfig

depends_lib-append  port:draco \
                    port:exiv2 \
                    port:expat \
                    port:gdal \
                    port:gdal-pdf \
                    port:geos \
                    port:gsl \
                    port:hdf5 \
                    port:libiconv \
                    port:libtasn1 \
                    port:libzip \
                    port:pdal \
                    port:proj \
                    port:protobuf3-cpp \
                    port:qca-qt6 \
                    port:qca-qt6-ossl \
                    port:qtkeychain-qt6 \
                    port:qscintilla-qt6 \
                    port:qwt-qt6 \
                    port:spatialite \
                    port:sqlite3 \
                    port:zlib \
                    port:zstd \
                    path:lib/libssl.dylib:openssl

qt6.depends_build-append \
                    qttools
qt6.depends_lib-append \
                    qt3d \
                    qt5compat \
                    qtdeclarative \
                    qtpositioning \
                    qtserialport \
                    qtsvg \
                    qtwebengine
qt6.depends_run-append \
                    sqlite-plugin

# Use MacPorts libraries and Python instead of the self-contained SDK layout.
patchfiles-append   patch-macports-bundle.diff \
                    patch-Info.plist.in.diff \
                    patch-python-home.diff

post-patch {
    reinplace "s|@PREFIX@|${prefix}|g" ${worksrcpath}/platform/macos/Info.plist.in
}

# QGIS 4 installs the Contents tree directly below CMAKE_INSTALL_PREFIX.
cmake.install_prefix \
                    ${applications_dir}/${app_name}.app
cmake.install_rpath ${cmake.install_prefix}/Contents/Frameworks \
                    ${qt6.dir}/lib \
                    ${prefix}/lib

# Let QGIS use @rpath IDs instead of the PortGroup's default app/lib directory.
configure.pre_args-delete \
                    -DCMAKE_INSTALL_NAME_DIR=\"${cmake.install_prefix}/lib\"

pre-configure {
    # Figure out HDF5's mpi include directory
    set mpl_include_dir ""
    if {![catch {set result [active_variants hdf5 openmpi]}]} {
        if {$result} {
            set mpl_include_dir "-I${prefix}/include/openmpi-mp"
        }
    }
    if {![catch {set result [active_variants hdf5 mpich]}]} {
        if {$result} {
            set mpl_include_dir "-I${prefix}/include/mpich-mp"
        }
    }
    if {$mpl_include_dir ne ""} {
        configure.cxxflags-append ${mpl_include_dir}
    }
}

configure.args-append \
                    -DENABLE_TESTS=OFF \
                    -DEXPAT_INCLUDE_DIR=${prefix}/include \
                    -DEXPAT_LIBRARY=${prefix}/lib/libexpat.dylib \
                    -DGDAL_CONFIG=${prefix}/bin/gdal-config \
                    -DGEOS_CONFIG=${prefix}/bin/geos-config \
                    -DLIBZIP_CONF_INCLUDE_DIR=${prefix}/lib/pkgconfig \
                    -DOpenCL_INCLUDE_DIR=${prefix}/include \
                    -DOPENCL_HPP_INCLUDE_DIR=${prefix}/include \
                    -DPROJ_ROOT=${prefix}/lib/proj9 \
                    -DQCA_INCLUDE_DIR=${qt6.dir}/include/QtCrypto \
                    -DQCA_LIBRARY=${qt6.dir}/lib/libqca-qt6.dylib \
                    -DQGIS_APP_NAME=${app_name} \
                    -DQGIS_MAC_BUNDLE=ON \
                    -DQSCINTILLA_INCLUDE_DIR=${qt6.dir}/include \
                    -DQSCINTILLA_LIBRARY=${qt6.dir}/lib/libqscintilla2_qt6.dylib \
                    -DQWT_INCLUDE_DIR=${qt6.dir}/lib/qwt.framework/Versions/Current/Headers \
                    -DQWT_LIBRARY=${qt6.dir}/lib/qwt.framework/Versions/Current/qwt \
                    -DUSE_CCACHE=OFF \
                    -DUSE_OPENCL=ON \
                    -DWITH_3D=ON \
                    -DWITH_BINDINGS=OFF \
                    -DWITH_PYTHON=OFF \
                    -DWITH_DRACO=ON \
                    -DWITH_GRASS7=OFF \
                    -DWITH_GRASS8=OFF \
                    -DWITH_GSL=ON \
                    -DWITH_INTERNAL_NLOHMANN_JSON=OFF \
                    -DWITH_INTERNAL_QWT=OFF \
                    -DWITH_INTERNAL_SPATIALINDEX=ON \
                    -DWITH_PDAL=ON \
                    -DWITH_QSPATIALITE=OFF \
                    -DWITH_SERVER=OFF

configure.cppflags-append \
                    -I${prefix}/lib/proj9/include
configure.ldflags-append \
                    "-Wl,-rpath,${qt6.dir}/lib" \
                    -L${prefix}/lib/proj9/lib

post-destroot {
    system "/usr/bin/codesign --force --deep --sign - [shellescape ${destroot}${cmake.install_prefix}]"
}

# GRASS variants
variant grass description "Build GRASS plugin" {
    depends_lib-append      port:grass
    global grass_gis_base
    pre-configure {
        set grass_gis_base      [exec ${prefix}/bin/grass --config path]
        configure.args-replace  -DWITH_GRASS8=OFF -DWITH_GRASS8=ON
        configure.args-append   -DGRASS_PREFIX8=${grass_gis_base}
    }
    post-patch {
        reinplace "s|command = None|command = '${prefix}/bin/grass'|g" \
            ${worksrcpath}/python/plugins/grassprovider/grass_utils.py
    }
}

# PostgreSQL variants
set pg_suffixes {18 17}
set pg_variants {}
foreach suffix ${pg_suffixes} {
    lappend pg_variants postgresql${suffix}
}
foreach suffix ${pg_suffixes} {
    set vrt postgresql${suffix}
    set pgversion [string index ${suffix} 0][string index ${suffix} 1]
    set index [lsearch -exact ${pg_variants} ${vrt}]
    set conf [lreplace ${pg_variants} ${index} ${index}]
    variant ${vrt} description "Use PostgreSQL ${pgversion}" conflicts {*}${conf} "
        depends_lib-append      port:${vrt}
        configure.args-append   -DPostgreSQL_ROOT=${prefix}/lib/${vrt} \
                                -DPostgreSQL_INCLUDE_DIR=${prefix}/include/${vrt} \
                                -DPostgreSQL_ADDITIONAL_VERSIONS=${pgversion}
    "
}
set pgdefault "if {"
foreach suffix ${pg_suffixes} {
    set pgdefault "${pgdefault}!\[variant_isset postgresql${suffix}\] && "
}
set pgdefault [string range ${pgdefault} 0 end-4]
set pgdefault "${pgdefault}} { default_variants +postgresql18 }"
eval ${pgdefault}

# Python variants
set python_suffixes {313 314}
set python_variants {}
set plugin_variants {}
foreach pyver ${python_suffixes} {
    lappend python_variants python${pyver}
    lappend plugin_variants plugin_support${pyver}
}
foreach pyver ${python_suffixes} {
    set vrt python${pyver}
    set pyversion [string index ${pyver} 0].[string range ${pyver} 1 end]
    set index [lsearch -exact ${python_variants} ${vrt}]
    set conf [lreplace ${python_variants} ${index} ${index}]

    variant ${vrt} description "Use Python ${pyversion} bindings" conflicts {*}${conf} "
        depends_lib-append      port:python${pyver} \
                                port:py${pyver}-pyqt6 \
                                port:py${pyver}-pyqt6-scintilla \
                                port:py${pyver}-gdal \
                                port:py${pyver}-six \
                                port:py${pyver}-protobuf3

        depends_build-append    port:py${pyver}-pyqt-builder \
                                path:${frameworks_dir}/Python.framework/Versions/${pyversion}/bin/sip-build:py${pyver}-sip

        depends_run-append      port:py${pyver}-psycopg2 \
                                port:py${pyver}-requests \
                                port:py${pyver}-owslib \
                                port:py${pyver}-yaml \
                                port:py${pyver}-jinja2 \
                                port:py${pyver}-pygments

        configure.env-append    PATH=${frameworks_dir}/Python.framework/Versions/${pyversion}/bin:$env(PATH)
        build.env-append        PATH=${frameworks_dir}/Python.framework/Versions/${pyversion}/bin:$env(PATH)
        destroot.env-append     PATH=${frameworks_dir}/Python.framework/Versions/${pyversion}/bin:$env(PATH)

        configure.args-append   -DPython_EXECUTABLE=${prefix}/bin/python${pyversion}
        configure.args-replace  -DWITH_BINDINGS=OFF -DWITH_BINDINGS=ON
        configure.args-replace  -DWITH_PYTHON=OFF -DWITH_PYTHON=ON
        configure.args-append   -DQSCI_SIP_DIR=${frameworks_dir}/Python.framework/Versions/${pyversion}/lib/python${pyversion}/site-packages/PyQt6/bindings

        post-patch {
            # Complies with py-gdal layout
            set gdal_py_prefix \"${worksrcpath}/python/plugins/processing/algs/gdal\"
            foreach file    {\"AssignProjection\" \
                             \"fillnodata\" \
                             \"gdal2tiles\" \
                             \"gdal2xyz\" \
                             \"gdalcalc\" \
                             \"pansharp\" \
                             \"pct2rgb\" \
                             \"polygonize\" \
                             \"proximity\" \
                             \"retile\" \
                             \"rgb2pct\" \
                             \"sieve\" } {
                reinplace -E \"s|else \\\".py\\\"|else '.py-${pyversion}'|\" \${gdal_py_prefix}/\${file}.py
            }
            foreach file    {\"merge\"  } {
                reinplace -E \"s|merge.command_ext()|'.py-${pyversion}'|\" \${gdal_py_prefix}/\${file}.py
            }
        }
    "

    set vrt2 plugin_support${pyver}
    set index2 [lsearch -exact ${plugin_variants} ${vrt2}]
    set conf2 [lreplace ${plugin_variants} ${index2} ${index2}]

    variant ${vrt2} description "Add common Python ${pyversion} modules for QGIS plugins" requires ${vrt} conflicts {*}${conf2} "
        depends_run-append  port:py${pyver}-affine \
                            port:py${pyver}-cycler \
                            port:py${pyver}-dateutil \
                            port:py${pyver}-fiona \
                            port:py${pyver}-geojson \
                            port:py${pyver}-h5py \
                            port:py${pyver}-llvmlite \
                            port:py${pyver}-markupsafe \
                            port:py${pyver}-matplotlib \
                            port:py${pyver}-numpy \
                            port:py${pyver}-opencv4 \
                            port:py${pyver}-pandas \
                            port:py${pyver}-patsy \
                            port:py${pyver}-Pillow \
                            port:py${pyver}-plotly \
                            port:py${pyver}-pyproj \
                            port:py${pyver}-rasterio \
                            port:py${pyver}-rsgislib \
                            port:py${pyver}-scikit-learn \
                            port:py${pyver}-scipy \
                            port:py${pyver}-seaborn \
                            port:py${pyver}-shapely \
                            port:py${pyver}-sip \
                            port:py${pyver}-statsmodels \
                            port:py${pyver}-termcolor
    "
}

# Python default
set python_default "if {"
foreach pyver ${python_suffixes} {
    set python_default "${python_default}!\[variant_isset python${pyver}\] && "
}
set python_default [string range ${python_default} 0 end-4]
set python_default "${python_default}} { default_variants +python314}"
eval ${python_default}

# Match plugin support to the selected interpreter unless explicitly disabled.
set have_plugin_support no
foreach pyver ${python_suffixes} {
    if {[variant_isset plugin_support${pyver}]} {
        set have_plugin_support yes
    }
}
if {!${have_plugin_support}} {
    foreach pyver ${python_suffixes} {
        if {[variant_isset python${pyver}]} {
            default_variants +plugin_support${pyver}
        }
    }
}

pre-configure {
    # Assert +pythonXY and +plugin_supportXY variants are in sync
    set supp_py_list [list]
    set pyth_py_list [list]
    foreach pyver ${python_suffixes} {
        if {[variant_isset plugin_support${pyver}]} {lappend supp_py_list ${pyver}}
        if {[variant_isset python${pyver}]} {lappend pyth_py_list ${pyver}}
    }
    if { [expr ([llength $supp_py_list] > 0) && ([llength $pyth_py_list] > 0)] &&
         [lindex $supp_py_list 0] != [lindex $pyth_py_list 0] } {
             set pyv [lindex $pyth_py_list 0]
             ui_error "${subport} +pythonXY and +plugin_supportXY variants must be in sync"
             return -code error "Try running `port install ${subport} +python${pyv} +plugin_support${pyv}`"
    }
}

variant server description "Builds with the server (FCGI) option" {
    depends_lib-append      port:fcgi
    pre-configure {
        return -code error "The +server option is currently broken (doesn’t link properly)"
    }
    configure.args-replace  -DWITH_SERVER=OFF -DWITH_SERVER=ON
}

notes-append \
    "QGIS 4 uses Qt 6. Plugins must support PyQt6 to work with this port."

notes-append \
    "The bundled spatialindex is used because of incompatibilities with spatialindex 2.1. \
    Deactivate the spatialindex port before building ${name}; it may be reactivated afterwards."

# Restrict livecheck to stable QGIS 4 tags, excluding QGIS 3 and future majors.
livecheck.regex     {final-(4_\d+_\d+)}
