%% SPDX-License-Identifier: BSD-3-Clause
%% SPDX-FileCopyrightText: 2020 Andrew Mayorov
%% SPDX-FileCopyrightText: 2022 Bram Verburg
%% SPDX-FileCopyrightText: 2024 Sebastian Strollo
%% SPDX-FileCopyrightText: 2025 Stritzinger GmbH
-module(rebar_sbom_purl).
% https://github.com/package-url/purl-spec
-export([hex/2, git/3, github/2, bitbucket/2, local_otp_app/2, local/2]).
hex(Name, Version) ->
purl(["hex", string:lowercase(Name)], Version).
git(_Name, "git@github.com:" ++ Github, Ref) ->
Repo = string:replace(Github, ".git", "", trailing),
github(Repo, Ref);
git(_Name, "https://github.com/" ++ Github, Ref) ->
Repo = string:replace(Github, ".git", "", trailing),
github(Repo, Ref);
git(_Name, "git://github.com/" ++ Github, Ref) ->
Repo = string:replace(Github, ".git", "", trailing),
github(Repo, Ref);
git(_Name, "git@bitbucket.org:" ++ Github, Ref) ->
Repo = string:replace(Github, ".git", "", trailing),
bitbucket(Repo, Ref);
git(_Name, "https://bitbucket.org/" ++ Github, Ref) ->
Repo = string:replace(Github, ".git", "", trailing),
bitbucket(Repo, Ref);
git(_Name, "git://bitbucket.org/" ++ Github, Ref) ->
Repo = string:replace(Github, ".git", "", trailing),
bitbucket(Repo, Ref);
%% Git dependence other than GitHub and BitBucket are not currently supported
git(_Name, _Git, _R) ->
undefined.
github(Repo, Ref) ->
[Organization, Name | _] = string:split(Repo, "/"),
purl(["github", string:lowercase(Organization), string:lowercase(Name)], Ref).
bitbucket(Repo, Ref) ->
[Organization, Name | _] = string:split(Repo, "/"),
purl(["bitbucket", string:lowercase(Organization), string:lowercase(Name)], Ref).
local_otp_app(Name, Version) ->
purl(["otp", string:lowercase(Name)], Version).
local(Name, Version) ->
purl(["generic", string:lowercase(Name)], Version).
purl(PathSegments, Version) ->
Path = lists:join("/", [escape(Segment) || Segment <- PathSegments]),
unicode:characters_to_binary(io_lib:format("pkg:~s@~s", [Path, escape(Version)])).
-if(?OTP_RELEASE >= 25).
escape(String) ->
uri_string:quote(String).
-else.
escape(String) ->
http_uri:encode(String).
-endif.