#ifndef BUILDER_H
#define BUILDER_H


/**
 * @file Builder.h
 * @author your name (you@domain.com)
 * @brief 
 * @version 0.1
 * @date 2025-02-22
 * 
 * @copyright Copyright (c) 2025
 * 
 */


 /**
 * 建造者模式
 *      1. 建造者模式有一个抽象生成器父类，定义了产品的创建接口
 *      2. 有n个具体生成器类，实现了抽象生成器父类的接口，负责创建产品的各个部件
 *      3. 有一个指挥者类，负责调用生成器类的接口，生成产品
 *      4. 有一个产品类，包含了产品的各个部件
 * 
 */



#include <vector>
#include <map>

#include "spdlog/spdlog.h"

/* ====================================================
 * 创建两个产品类，存放生成的每个部件
 * ==================================================== */


class SunnyShip
{

public:
    SunnyShip() {}
    ~SunnyShip() {}

    /* 添加部件 */
    void addPart(const std::string& part)
    {
        m_parts.push_back(part);
    }
    /* 展示部件 */
    void ShowParts()
    {
        for (auto part : m_parts)
        {
            SPDLOG_INFO("Part: {}", part);
        }
    }

private:
    std::vector<std::string> m_parts;

};

/**
 * @brief 美丽号零件有区别，使用map来存储
 * 
 */
class MerryShip
{

public:
    MerryShip() {}
    ~MerryShip() {}

    /* 添加部件，键是部件材料，值是部件名称 */
    void addPart(const std::string& name, const std::string& part)
    {
        m_parts.insert(std::make_pair(name, part));
    }
    /* 展示部件 */
    void ShowParts()
    {
        for (auto part : m_parts)
        {
            SPDLOG_INFO("{}:{}", part.first, part.second);
        }
    }

private:
    std::map<std::string, std::string> m_parts;     /* 部件材料和部件名称 */

};


/* ====================================================
 * 创建一个抽象生成器父类，定义了产品的创建接口
 * ==================================================== */

class ShipBuilder
{
public:
    virtual ~ShipBuilder() {}
    virtual void reset() = 0;
    virtual void buildBody() = 0;       /* 创建船体 */
    virtual void buildEngine() = 0;     /* 创建引擎 */
    virtual void buildWeapon() = 0;     /* 创建武器 */
    virtual void buildInterior() = 0;   /* 创建内饰 */
};

/**
 * @brief Sunny号生成器
 * 
 */
 class SunnyShipBuilder : public ShipBuilder
 {
public:
    SunnyShipBuilder() { reset(); }
    ~SunnyShipBuilder() 
    {
        if(m_ship != nullptr)
        {
            delete m_ship;
        }
    }

    void reset() override
    {
        m_ship = new SunnyShip();
    }
    void buildBody() override
    {
        m_ship->addPart("Sunny Body");
    }
    void buildEngine() override
    {
        m_ship->addPart("Sunny Engine");
    }
    void buildWeapon() override
    {
        m_ship->addPart("Sunny Weapon");
    }
    void buildInterior() override
    {
        m_ship->addPart("Sunny Interior");
    }
    /* 提供一个获取船的接口 */
    SunnyShip* getShip()
    {
        SunnyShip* ship = m_ship;
        m_ship = nullptr;
        return ship;
    }

private:
    SunnyShip* m_ship = nullptr;

 };

 /**
  * @brief Merry号生成器
  * 
  */

class MerryShipBuilder : public ShipBuilder
{
public:
    MerryShipBuilder() { reset(); }
    ~MerryShipBuilder() 
    {
        if(m_ship != nullptr)
        {
            delete m_ship;
        }
    }

    void reset() override
    {
        m_ship = new MerryShip();
    }
    void buildBody() override
    {
        m_ship->addPart("Wood", "Merry Body");
    }
    void buildEngine() override
    {
        m_ship->addPart("Iron", "Merry Engine");
    }
    void buildWeapon() override
    {
        m_ship->addPart("Cannon", "Merry Weapon");
    }
    void buildInterior() override
    {
        m_ship->addPart("Gold", "Merry Interior");
    }
    /* 提供一个获取船的接口 */
    MerryShip* getShip()
    {
        MerryShip* ship = m_ship;
        m_ship = nullptr;
        return ship;
    }



private:
    MerryShip* m_ship = nullptr;

};

/* ====================================================
 * 创建一个船厂(主管)，生成不同类型的船
 * ==================================================== */

class ShipFactory
{
    
public:
    ShipFactory() {}
    ~ShipFactory() {}

    /* 设置Builder */
    void setBuilder(ShipBuilder* builder)
    {
        m_builder = builder;
    }
    /* 建造简约型的船 */
    void builderSimpleShip()
    {
        m_builder->buildBody();
        m_builder->buildEngine();
    }

    /* 建造标准型的船 */
    void builderStandardShip()
    {
        builderSimpleShip();
        m_builder->buildWeapon();
    }

    /* 建造豪华型的船 */
    void builderRegalShip()
    {
        builderStandardShip();
        m_builder->buildInterior();
    }

public:
    ShipBuilder* m_builder = nullptr;

};

/* ====================================================
 * 创建船，使用全局函数来创建
 * ==================================================== */

 /* 创建Sunny号 */
void buildSunnyShip();
/* 创建Merry号 */
void buildMerryShip();



#endif // BUILDER_H
