const fs = require('fs')
const path = require('path')
const os = require('os')
const { describe, it, before, test } = require('node:test')
const assert = require('node:assert/strict')
const { discoverCodeLibraryItemsFromRoot } = require('./library-update')

describe('discoverCodeLibraryItemsFromRoot', () => {
  let tmpDir

  before(() => {
    tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), 'bild-lib-update-'))
    const homepage = path.join(tmpDir, 'Homepage')
    fs.mkdirSync(homepage, { recursive: true })
    fs.writeFileSync(
      path.join(homepage, 'hero.jsx'),
      'export default function Hero() { return null; }\n',
    )
    fs.writeFileSync(
      path.join(homepage, 'hero.json'),
      JSON.stringify({
        name: 'Hero',
        description: 'Hero block',
        type: 'Homepage',
        image: 'https://example.com/preview.png',
        templateId: 'hero',
      }),
    )
  })

  it('discovers code files with sibling metadata', () => {
    const items = discoverCodeLibraryItemsFromRoot(tmpDir)
    assert.equal(items.length, 1)
    assert.equal(items[0].templateId, 'hero')
    assert.equal(items[0].type, 'Homepage')
    assert.equal(items[0].name, 'Hero')
    assert.ok(items[0].filePath.endsWith('hero.jsx'))
  })

  it('throws when root does not exist', () => {
    assert.throws(
      () => discoverCodeLibraryItemsFromRoot(path.join(tmpDir, 'missing')),
      /does not exist/,
    )
  })
})

test('updateCommand exits when app id is missing', async () => {
  const config = require('../lib/config')
  const roles = require('../lib/roles')
  const originalGetConfig = config.getConfig
  const originalRequireRole = roles.requireDeveloperRoleForApp

  config.getConfig = () => ({ defaultAppId: null, sitePath: null })
  roles.requireDeveloperRoleForApp = async () => {}

  delete require.cache[require.resolve('./library-update')]
  const updateCommandFn = require('./library-update')

  let exitCode
  const originalExit = process.exit
  process.exit = (code) => {
    exitCode = code
    throw new Error('process.exit')
  }

  try {
    await assert.rejects(() => updateCommandFn([], { appId: null }), /process\.exit/)
    assert.equal(exitCode, 1)
  } finally {
    process.exit = originalExit
    config.getConfig = originalGetConfig
    roles.requireDeveloperRoleForApp = originalRequireRole
    delete require.cache[require.resolve('./library-update')]
  }
})
