// SPDX-License-Identifier: Apache-2.0
// Copyright 2025 Letter Combinations Solution
//
// Licensed 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.

#ifndef LETTER_COMBINATIONS_H
#define LETTER_COMBINATIONS_H

#include <vector>
#include <string>
#include <unordered_map>

/**
 * @class LetterCombinations
 * @brief Solves the "Letter Combinations of a Phone Number" problem
 * 
 * Given a string containing digits from 2-9 inclusive, returns all possible 
 * letter combinations that the number could represent based on phone keypad mapping.
 * 
 * Phone keypad mapping:
 * 2: abc, 3: def, 4: ghi, 5: jkl, 6: mno, 7: pqrs, 8: tuv, 9: wxyz
 * 
 * Example:
 * Input: "23"
 * Output: ["ad","ae","af","bd","be","bf","cd","ce","cf"]
 * 
 * Time Complexity: O(3^N * 4^M) where N is digits with 3 letters, M is digits with 4 letters
 * Space Complexity: O(3^N * 4^M) for storing all combinations
 */
class LetterCombinations {
public:
    // LIFECYCLE
    /**
     * @brief Constructor - initializes digit to letters mapping
     */
    LetterCombinations();
    
    /**
     * @brief Destructor
     */
    ~LetterCombinations() = default;
    
    // OPERATORS
    // Copy constructor and assignment operator use default implementations
    LetterCombinations(const LetterCombinations&) = default;
    LetterCombinations& operator=(const LetterCombinations&) = default;
    
    // OPERATIONS
    /**
     * @brief Get all letter combinations for given digits (recursive approach)
     * @param digits String containing digits 2-9
     * @return Vector of all possible letter combinations
     */
    std::vector<std::string> GetCombinations(const std::string& digits);
    
    /**
     * @brief Get all letter combinations for given digits (iterative approach)
     * @param digits String containing digits 2-9
     * @return Vector of all possible letter combinations
     */
    std::vector<std::string> GetCombinationsIterative(const std::string& digits);
    
    /**
     * @brief Get letters mapped to a specific digit
     * @param digit Digit from 2-9
     * @return String containing letters for the digit
     */
    std::string GetLettersForDigit(int digit) const;
    
    /**
     * @brief Print combinations to console (utility method)
     * @param combinations Vector of combinations to print
     */
    void PrintCombinations(const std::vector<std::string>& combinations) const;
    
    /**
     * @brief Run demonstration with test cases
     */
    void RunDemo();

private:
    // OPERATIONS
    /**
     * @brief Recursive helper to generate combinations
     * @param digits Input digit string
     * @param digit_index Current position in digits string
     * @param current_combination Current combination being built
     * @param result Reference to result vector
     */
    void GenerateCombinationsRecursive(const std::string& digits, 
                                      int digit_index,
                                      std::string& current_combination,
                                      std::vector<std::string>& result);
    
    /**
     * @brief Validate input contains only digits 2-9
     * @param digits Input string to validate
     * @return True if valid, false otherwise
     */
    bool IsValidInput(const std::string& digits) const;
    
    // ATTRIBUTES
    /**
     * @brief Mapping from digit to corresponding letters
     */
    std::unordered_map<int, std::string> mDigitMap;
};

#endif // LETTER_COMBINATIONS_H