# encoding: utf-8
# api: pep517
# title: flit backend
# description: wraps flit_core.buildapi
# version: 0.1
# depends: python:flit (>=3.0, <4.0)
# license: BSD-3-Clause
# priority: extra
# src: ~/.local/lib/python3.8/site-packages/flit_core/
#
# This is supposed to become an alternative to pluginconf.setup,
# using flit as pep517 build backend. But adding automagic field
# lookup of course.
# 
#
# [build-system]
# requires = ["flit_core", "pluginconf"]
# build-backend = "pluginconf.flit"
#
# [project]
# name = "foobar"
# dynamic = ["version", "description"]
#
#

import os
import re
import os.path
import pathlib
import functools

import pluginconf
import pluginconf.setup

import flit_core.common


#-- patch functions

def patch_flit_config(path):
    """ read_flit_config() with preset dynamic fields """
    d = tomllib.loads(path.read_text('utf-8'))
    
    # make fields dynamic
    if not "dynamic" in d["project"]:
        d["project"]["dynamic"] = []
    for dyn in ['description', 'version']: 
        if dyn in d["project"]:
            del d["project"][dyn]
        if not dyn in d["project"]["dynamic"]:
            d["project"]["dynamic"].append(dyn)
    print(d)

    # turn it into LoadedConfig
    return prep_toml_config(d, path)

# override make_metadata
def patch_metadata(module, ini_info):
    meta = {
        "name": module.name,
        "provides": [module.name]
    }
    meta.update(ini_info.metadata)
    meta.update(
        pmd_meta(filename=module.file)
    )
    return flit_core.common.Metadata(meta)

# inject
flit_core.common.make_metadata = patch_metadata


#-- map plugin meta to flit Metadata

def pmd_meta(filename):
    """ enjoin PMD fields with flit meta data """
    pmd  = pluginconf.plugin_meta(filename=filename)
    
    meta = dict(
        summary = pmd.get("description"),
        version = pmd.get("version"),
        home_page = pmd.get("url"),
        author = pmd.get("author"),  # should split this into mail and name
        author_email = None,
        maintainer = None,
        maintainer_email = None,
        license = pmd.get("license"),
        keywords = pmd.get("keywords"),
        download_url = None,
        requires_python = pluginconf.setup._python_requires(pmd).get("python_requires", ">= 2.7"),
        platform = (),
        supported_platform = (),
        classifiers = list(pluginconf.setup._classifiers(pmd))
                    + pluginconf.setup._trove_license(pmd)
                    + pluginconf.setup._trove_status(pmd),
        provides = (),
        requires = pluginconf.setup._install_requires(pmd).get("install_requires") or (),
        obsoletes = (),
        project_urls = [f"{k}, {v}" for k,v in pluginconf.setup._project_urls(pmd).items()],
        provides_dist = (),
        requires_dist = pluginconf.setup._install_requires(pmd).get("install_requires") or (),
        obsoletes_dist = (),
        requires_external = (),
        provides_extra = (),
    )
    meta.update({k[5:]: v for k,v in pluginconf.setup._plugin_doc(pmd).items()})
    meta.update({k[5:]: v for k,v in pluginconf.setup._get_readme().items()})

    return meta


# 'metadata', 'module', 'referenced_files', 'reqs_by_extra',
# 'sdist_exclude_patterns', 'sdist_include_patterns']
#
# ini.metadata =
#   {'name': 'basename', 'requires_dist': []}
#
# ini.module =
#   basename
#
# ini.dynamic_metadata =
#   {'version', 'description'}
#
# ini.__dict__ =
# {
# 'module': 'pluginconf',
# 'metadata': {
#   'name': 'pluginconf',
#   'version': '1.0',
#   'summary': '...',
#   'requires_dist': []
# },
# 'reqs_by_extra': {},
# 'entrypoints': {},
# 'referenced_files': [],
# 'sdist_include_patterns': [],
# 'sdist_exclude_patterns': [],
# 'dynamic_metadata': [],
# 'data_directory': None
# }

#module = Module(ini.module, pathlib.Path.cwd())
#print(module.__dict__)
#print(module.file)
# {'name': 'pluginconf', 'path':
# PosixPath('/home/mario/projects/pluginconf/pluginconf'), 'is_package':
# True, 'prefix': '', 'source_dir':
# PosixPath('/home/mario/projects/pluginconf')}

#MD = patch_metadata(module, ini)
#print(MD.__dict__)


import flit_core.buildapi

flit_core.buildapi.prepare_metadata_for_build_wheel("./build/")



#-- buildapi
#
# These need to be late imports;
# else they'll bind the original helper functions
from flit_core.buildapi import (
    get_requires_for_build_wheel,
    get_requires_for_build_sdist,
    get_requires_for_build_editable,
    prepare_metadata_for_build_wheel,
    prepare_metadata_for_build_editable,
    build_wheel,
    build_editable,
    build_sdist,
)

import flit

# as invocation point
def main(argv=None):
    return flit.main(argv)
