// 1. 【引入和实例化】
// 和 http.createServer() 类似，这是创建 Fastify 服务器实例的第一步
// 我们传入 { logger: true } 来开启 Fastify 自带的、性能极高的日志功能
const fastify = require('fastify')({ logger: true });

// 模拟一个简单的数据库
const users = [
  { id: 1, name: '张三', email: 'zhangsan@example.com' },
  { id: 2, name: '李四', email: 'lisi@example.com' },
];

// 2. 【核心功能：路由 (Routing)】
// 这是最基础的 GET 路由，类似于 Web 服务器的“欢迎页面”
fastify.get('/', async (request, reply) => {
  // request 对象包含了所有请求信息
  // reply 对象用于构建和发送响应
  return { message: '欢迎来到 Fastify 核心功能示例!' };
});

// GET 路由：带路径参数 (Params)
// :id 是一个占位符，可以匹配 /users/1, /users/2 等
fastify.get('/users/:id', async (request, reply) => {
  const userId = parseInt(request.params.id, 10); // 从路径中获取 id
  const user = users.find(u => u.id === userId);

  if (!user) {
    // 使用 reply 对象设置状态码并发送响应
    return reply.status(404).send({ error: '用户未找到' });
  }
  return user;
});

// GET 路由：带查询字符串 (Query String)
// 匹配 /search?name=张三
fastify.get('/search', async (request, reply) => {
  const name = request.query.name; // 从 ?key=value 中获取
  const results = users.filter(u => u.name.includes(name));
  return results;
});

// POST 路由：处理请求体 (Body)
// 用于创建新资源
fastify.post('/users', async (request, reply) => {
  const newUser = request.body; // 获取 POST 请求的 JSON 数据
  newUser.id = users.length + 1; // 简单地分配一个新 ID
  users.push(newUser);

  // 返回 201 Created 状态码，并附上新创建的用户数据
  return reply.status(201).send(newUser);
});

// 3. 【核心功能：Schema (模式验证与序列化)】
// 这是 Fastify 性能超群的关键！
// 它能在请求进入处理函数前自动验证数据，在响应发送前自动快速序列化数据
const createUserSchema = {
  // body 部分定义了对 POST 请求体的验证规则
  body: {
    type: 'object',
    required: ['name', 'email'], // name 和 email 字段是必需的
    properties: {
      name: { type: 'string' },
      email: { type: 'string', format: 'email' }, // 甚至可以验证 email 格式
    },
  },
  // response 部分定义了响应的格式，Fastify 会用它来极速序列化 JSON
  response: {
    201: { // 201 状态码对应的响应格式
      type: 'object',
      properties: {
        id: { type: 'integer' },
        name: { type: 'string' },
        email: { type: 'string' },
      },
    },
  },
};

// 带 Schema 的 POST 路由
fastify.post('/users-validated', { schema: createUserSchema }, async (request, reply) => {
  // 如果请求体不符合上面的 body schema，代码根本不会执行到这里
  // Fastify 会自动返回一个 400 Bad Request 错误
  const newUser = request.body;
  newUser.id = users.length + 1;
  users.push(newUser);

  // 因为有 response schema，这里返回的数据会被安全、快速地格式化
  return reply.status(201).send(newUser);
});

// 4. 【核心功能：钩子 (Hooks)】
// Hooks 允许你在请求生命周期的特定点执行代码，非常适合做认证、日志记录等
fastify.addHook('onRequest', async (request, reply) => {
  // 这个钩子会在每个请求匹配到路由之前执行
  // 我们可以用它来打印一些全局信息
  fastify.log.info(`收到一个 ${request.method} 请求，访问路径: ${request.url}`);
});

// 5. 【启动服务器】
// Fastify 的启动是异步的，所以我们用 async/await
const start = async () => {
  try {
    // 监听 3000 端口
    await fastify.listen({ port: 3000, host: '0.0.0.0'});
  } catch (err) {
    // 如果启动失败，打印错误日志并退出
    fastify.log.error(err);
    process.exit(1);
  }
};

start();