# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements.  See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership.  The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License.  You may obtain a copy of the License at
#
#   http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied.  See the License for the
# specific language governing permissions and limitations
# under the License.

name: Issue Bot

on:
  issues:
    types:
      - opened

permissions:
  contents: read

jobs:
  label_components:
    name: Label Components
    if: github.event.issue.pull_request == null
    runs-on: ubuntu-latest
    permissions:
      issues: write
    steps:
      - uses: actions/github-script@v8
        with:
          script: |
            const moved_repos = {
              "Go": "arrow-go",
              "Java": "arrow-java",
              "JavaScript": "arrow-js",
              "Julia": "arrow-julia",
              "Rust": "arrow-rs",
              "Swift": "arrow-swift",
              "C#": "arrow-dotnet",
              "DataFusion": "datafusion",
            };

            let repo_moved_msg = (component, repo) =>
              `Thanks for your report! The ${component} implementation has moved to https://github.com/apache/${repo}.\n\n` +
              `This issue has been closed automatically - please open a new issue there.`;

            let split_body = context.payload.issue.body.split('### Component(s)');
            if (split_body.length != 2) throw new Error('No components found!');

            let current_labels = await github.rest.issues.listLabelsOnIssue({
              "owner": context.repo.owner,
              "repo": context.repo.repo,
              "per_page": 100,
              "issue_number": context.payload.issue.number,
            });

            let current_label_names = current_labels.data.map(label => label.name);

            // keep non-component labels
            let non_component_labels = current_label_names.filter(
              label => !label.startsWith("Component: ")
            );

            let components = split_body[1]
              .split(',')
              .map(component => component.trim());
            let moved_component = components.find(comp => comp in moved_repos);

            if (moved_component) {
               await github.rest.issues.createComment({
                "owner": context.repo.owner,
                "repo": context.repo.repo,
                "issue_number": context.payload.issue.number,
                "body": repo_moved_msg(moved_component, moved_repos[moved_component]),
              });
              await github.rest.issues.update({
                "owner": context.repo.owner,
                "repo": context.repo.repo,
                "issue_number": context.payload.issue.number,
                "state": "closed",
              });
              return;
            }

            let component_labels = components.map(component => "Component: " + component);

            let repo_labels = await github.rest.issues.listLabelsForRepo({
              "owner": context.repo.owner,
              "repo": context.repo.repo,
              "per_page": 100,
            });

            // this removes nonexistent labels
            component_labels = component_labels.filter(
              label => repo_labels.data.some(repo_label => repo_label.name === label)
            );

            if (component_labels.length == 0) throw new Error('No components found!');

            await github.rest.issues.setLabels({
              "owner": context.repo.owner,
              "repo": context.repo.repo,
              "issue_number": context.payload.issue.number,
              "labels": component_labels.concat(non_component_labels),
            });
